From 50deb845a8ccf01518e256b867ea3aa191349ef7 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 25 Aug 2023 16:41:34 -0300 Subject: [PATCH 01/26] refactor: use Hathor simulator on events simulator CLI --- .../event_forwarding_websocket_factory.py | 32 +++ .../event_forwarding_websocket_protocol.py | 47 ++++ .../cli/events_simulator/events_simulator.py | 48 ++++- hathor/cli/events_simulator/scenario.py | 90 ++++++-- .../events_simulator/scenarios/__init__.py | 0 .../scenarios/only_load_events.py | 24 --- .../scenarios/reorg_events.py | 60 ------ ...le_chain_blocks_and_transactions_events.py | 58 ----- .../single_chain_one_block_events.py | 28 --- .../event/test_event_simulation_scenarios.py | 204 +++++++----------- 10 files changed, 274 insertions(+), 317 deletions(-) create mode 100644 hathor/cli/events_simulator/event_forwarding_websocket_factory.py create mode 100644 hathor/cli/events_simulator/event_forwarding_websocket_protocol.py delete mode 100644 hathor/cli/events_simulator/scenarios/__init__.py delete mode 100644 hathor/cli/events_simulator/scenarios/only_load_events.py delete mode 100644 hathor/cli/events_simulator/scenarios/reorg_events.py delete mode 100644 hathor/cli/events_simulator/scenarios/single_chain_blocks_and_transactions_events.py delete mode 100644 hathor/cli/events_simulator/scenarios/single_chain_one_block_events.py diff --git a/hathor/cli/events_simulator/event_forwarding_websocket_factory.py b/hathor/cli/events_simulator/event_forwarding_websocket_factory.py new file mode 100644 index 000000000..15e5e70d1 --- /dev/null +++ b/hathor/cli/events_simulator/event_forwarding_websocket_factory.py @@ -0,0 +1,32 @@ +# 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 typing import Any + +from twisted.internet.interfaces import IAddress + +from hathor.cli.events_simulator.event_forwarding_websocket_protocol import EventForwardingWebsocketProtocol +from hathor.event.websocket import EventWebsocketFactory +from hathor.simulator import Simulator + + +class EventForwardingWebsocketFactory(EventWebsocketFactory): + def __init__(self, simulator: Simulator, *args: Any, **kwargs: Any) -> None: + self._simulator = simulator + super().__init__(*args, **kwargs) + + def buildProtocol(self, _: IAddress) -> EventForwardingWebsocketProtocol: + protocol = EventForwardingWebsocketProtocol(self._simulator) + protocol.factory = self + return protocol diff --git a/hathor/cli/events_simulator/event_forwarding_websocket_protocol.py b/hathor/cli/events_simulator/event_forwarding_websocket_protocol.py new file mode 100644 index 000000000..da3530572 --- /dev/null +++ b/hathor/cli/events_simulator/event_forwarding_websocket_protocol.py @@ -0,0 +1,47 @@ +# 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 typing import TYPE_CHECKING + +from autobahn.websocket import ConnectionRequest + +from hathor.event.websocket import EventWebsocketProtocol +from hathor.simulator import Simulator + +if TYPE_CHECKING: + from hathor.cli.events_simulator.event_forwarding_websocket_factory import EventForwardingWebsocketFactory + + +class EventForwardingWebsocketProtocol(EventWebsocketProtocol): + factory: 'EventForwardingWebsocketFactory' + + def __init__(self, simulator: Simulator) -> None: + self._simulator = simulator + super().__init__() + + def onConnect(self, request: ConnectionRequest) -> None: + super().onConnect(request) + self._simulator.run(60) + + def onOpen(self) -> None: + super().onOpen() + self._simulator.run(60) + + def onClose(self, wasClean: bool, code: int, reason: str) -> None: + super().onClose(wasClean, code, reason) + self._simulator.run(60) + + def onMessage(self, payload: bytes, isBinary: bool) -> None: + super().onMessage(payload, isBinary) + self._simulator.run(60) diff --git a/hathor/cli/events_simulator/events_simulator.py b/hathor/cli/events_simulator/events_simulator.py index d4beea9de..5491d3c28 100644 --- a/hathor/cli/events_simulator/events_simulator.py +++ b/hathor/cli/events_simulator/events_simulator.py @@ -12,10 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os from argparse import ArgumentParser, Namespace +from autobahn.twisted.resource import WebSocketResource +from structlog import get_logger +from twisted.web.resource import Resource +from twisted.web.server import Site + DEFAULT_PORT = 8080 +logger = get_logger() + def create_parser() -> ArgumentParser: from hathor.cli.events_simulator.scenario import Scenario @@ -26,14 +34,17 @@ def create_parser() -> ArgumentParser: parser.add_argument('--scenario', help=f'One of {possible_scenarios}', type=str, required=True) parser.add_argument('--port', help='Port to run the WebSocket server', type=int, default=DEFAULT_PORT) + parser.add_argument('--seed', help='The seed used to create simulated events', type=int) return parser def execute(args: Namespace) -> None: + from hathor.conf import UNITTESTS_SETTINGS_FILEPATH + os.environ['HATHOR_CONFIG_YAML'] = UNITTESTS_SETTINGS_FILEPATH + from hathor.cli.events_simulator.event_forwarding_websocket_factory import EventForwardingWebsocketFactory from hathor.cli.events_simulator.scenario import Scenario - from hathor.event.storage import EventMemoryStorage - from hathor.event.websocket import EventWebsocketFactory + from hathor.simulator import Simulator from hathor.util import reactor try: @@ -42,15 +53,36 @@ def execute(args: Namespace) -> None: possible_scenarios = [scenario.name for scenario in Scenario] raise ValueError(f'Invalid scenario "{args.scenario}". Choose one of {possible_scenarios}') from e - storage = EventMemoryStorage() + log = logger.new() + simulator = Simulator(args.seed) + simulator.start() + builder = simulator.get_default_builder() \ + .disable_full_verification() \ + .enable_event_queue() + + manager = simulator.create_peer(builder) + event_ws_factory = manager._event_manager._event_ws_factory + assert event_ws_factory is not None + + forwarding_ws_factory = EventForwardingWebsocketFactory( + simulator=simulator, + reactor=reactor, + event_storage=event_ws_factory._event_storage + ) + + manager._event_manager._event_ws_factory = forwarding_ws_factory - for event in scenario.value: - storage.save_event(event) + root = Resource() + api = Resource() + root.putChild(b'v1a', api) + api.putChild(b'event_ws', WebSocketResource(forwarding_ws_factory)) + site = Site(root) - factory = EventWebsocketFactory(reactor, storage) + log.info('Started simulating events', scenario=args.scenario, seed=simulator.seed) - factory.start() - reactor.listenTCP(args.port, factory) + forwarding_ws_factory.start() + scenario.simulate(simulator, manager) + reactor.listenTCP(args.port, site) reactor.run() diff --git a/hathor/cli/events_simulator/scenario.py b/hathor/cli/events_simulator/scenario.py index 90426a198..db2b6db27 100644 --- a/hathor/cli/events_simulator/scenario.py +++ b/hathor/cli/events_simulator/scenario.py @@ -13,21 +13,83 @@ # limitations under the License. from enum import Enum +from typing import TYPE_CHECKING -from hathor.cli.events_simulator.scenarios.only_load_events import ONLY_LOAD_EVENTS -from hathor.cli.events_simulator.scenarios.reorg_events import REORG_EVENTS -from hathor.cli.events_simulator.scenarios.single_chain_blocks_and_transactions_events import ( - SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS_EVENTS, -) -from hathor.cli.events_simulator.scenarios.single_chain_one_block_events import SINGLE_CHAIN_ONE_BLOCK_EVENTS +if TYPE_CHECKING: + from hathor.manager import HathorManager + from hathor.simulator import Simulator class Scenario(Enum): - """ - NOTE: The lists of events used in each scenario's enum value below were obtained from the tests in - tests.event.test_simulation.TestEventSimulation - """ - ONLY_LOAD = ONLY_LOAD_EVENTS - SINGLE_CHAIN_ONE_BLOCK = SINGLE_CHAIN_ONE_BLOCK_EVENTS - SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS = SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS_EVENTS - REORG = REORG_EVENTS + ONLY_LOAD = 'ONLY_LOAD' + SINGLE_CHAIN_ONE_BLOCK = 'SINGLE_CHAIN_ONE_BLOCK' + SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS = 'SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS' + REORG = 'REORG' + + def simulate(self, simulator: 'Simulator', manager: 'HathorManager') -> None: + simulate_fns = { + Scenario.ONLY_LOAD: simulate_only_load, + Scenario.SINGLE_CHAIN_ONE_BLOCK: simulate_single_chain_one_block, + Scenario.SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS: simulate_single_chain_blocks_and_transactions, + Scenario.REORG: simulate_reorg, + } + + simulate_fn = simulate_fns[self] + + simulate_fn(simulator, manager) + + +def simulate_only_load(simulator: 'Simulator', _manager: 'HathorManager') -> None: + simulator.run(60) + + +def simulate_single_chain_one_block(simulator: 'Simulator', manager: 'HathorManager') -> None: + from tests.utils import add_new_blocks + add_new_blocks(manager, 1) + simulator.run(60) + + +def simulate_single_chain_blocks_and_transactions(simulator: 'Simulator', manager: 'HathorManager') -> None: + from hathor import daa + from hathor.conf import HathorSettings + from tests.utils import add_new_blocks, gen_new_tx + + settings = HathorSettings() + assert manager.wallet is not None + address = manager.wallet.get_unused_address(mark_as_used=False) + + add_new_blocks(manager, settings.REWARD_SPEND_MIN_BLOCKS + 1) + simulator.run(60) + + tx = gen_new_tx(manager, address, 1000) + tx.weight = daa.minimum_tx_weight(tx) + tx.update_hash() + assert manager.propagate_tx(tx, fails_silently=False) + simulator.run(60) + + tx = gen_new_tx(manager, address, 2000) + tx.weight = daa.minimum_tx_weight(tx) + tx.update_hash() + assert manager.propagate_tx(tx, fails_silently=False) + simulator.run(60) + + add_new_blocks(manager, 1) + simulator.run(60) + + +def simulate_reorg(simulator: 'Simulator', manager: 'HathorManager') -> None: + from hathor.simulator import FakeConnection + from tests.utils import add_new_blocks + + builder = simulator.get_default_builder() + manager2 = simulator.create_peer(builder) + + add_new_blocks(manager, 1) + simulator.run(60) + + add_new_blocks(manager2, 2) + simulator.run(60) + + connection = FakeConnection(manager, manager2) + simulator.add_connection(connection) + simulator.run(60) diff --git a/hathor/cli/events_simulator/scenarios/__init__.py b/hathor/cli/events_simulator/scenarios/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/hathor/cli/events_simulator/scenarios/only_load_events.py b/hathor/cli/events_simulator/scenarios/only_load_events.py deleted file mode 100644 index f8c588441..000000000 --- a/hathor/cli/events_simulator/scenarios/only_load_events.py +++ /dev/null @@ -1,24 +0,0 @@ -# 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 hathor.event.model.base_event import BaseEvent, EventType -from hathor.event.model.event_data import EmptyData, TxData, TxMetadata, TxOutput - -ONLY_LOAD_EVENTS = [ - BaseEvent(peer_id='97c14daade28cfe68d5854361bf6d5754b2a1f81e38fb44fe51367f1eb254d11', id=0, timestamp=1572653259.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), # noqa E501 - BaseEvent(peer_id='97c14daade28cfe68d5854361bf6d5754b2a1f81e38fb44fe51367f1eb254d11', id=1, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='97c14daade28cfe68d5854361bf6d5754b2a1f81e38fb44fe51367f1eb254d11', id=2, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='97c14daade28cfe68d5854361bf6d5754b2a1f81e38fb44fe51367f1eb254d11', id=3, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='97c14daade28cfe68d5854361bf6d5754b2a1f81e38fb44fe51367f1eb254d11', id=4, timestamp=1572653259.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None) # noqa E501 -] diff --git a/hathor/cli/events_simulator/scenarios/reorg_events.py b/hathor/cli/events_simulator/scenarios/reorg_events.py deleted file mode 100644 index b65872bc4..000000000 --- a/hathor/cli/events_simulator/scenarios/reorg_events.py +++ /dev/null @@ -1,60 +0,0 @@ -# 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 hathor.event.model.base_event import BaseEvent, EventType -from hathor.event.model.event_data import EmptyData, ReorgData, TxData, TxMetadata, TxOutput - -REORG_EVENTS = [ - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=0, timestamp=1572653259.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=1, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=2, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=3, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=4, timestamp=1572653259.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=5, timestamp=1572653289.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2'], twins=[], accumulated_weight=2.0, score=2.0, first_block='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=6, timestamp=1572653289.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', nonce=3849224008, timestamp=1572653289, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUCVEmDq3zPs6KV42QQDe7R/jVSsCIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=7, timestamp=1572653289.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2'], twins=[], accumulated_weight=2.0, score=2.0, first_block='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=8, timestamp=1572653289.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', nonce=3849224008, timestamp=1572653289, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUCVEmDq3zPs6KV42QQDe7R/jVSsCIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=9, timestamp=1572653290.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', nonce=2571046484, timestamp=1572653290, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7TohZ0qkDwOGVvk902Ee5ocSLjiIrA==', token_data=0)], parents=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=10, timestamp=1572653290.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', nonce=2571046484, timestamp=1572653290, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7TohZ0qkDwOGVvk902Ee5ocSLjiIrA==', token_data=0)], parents=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=11, timestamp=1572653291.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', nonce=2810868913, timestamp=1572653291, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUJ1IwZftpI4amogcnKJWgc6/eJWuIrA==', token_data=0)], parents=['6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=12, timestamp=1572653291.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', nonce=2810868913, timestamp=1572653291, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUJ1IwZftpI4amogcnKJWgc6/eJWuIrA==', token_data=0)], parents=['6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=13, timestamp=1572653292.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', nonce=2900453906, timestamp=1572653292, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUA6/mkfdCoE0/VMGDn4pFDLOkJF6IrA==', token_data=0)], parents=['34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=14, timestamp=1572653292.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', nonce=2900453906, timestamp=1572653292, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUA6/mkfdCoE0/VMGDn4pFDLOkJF6IrA==', token_data=0)], parents=['34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=15, timestamp=1572653293.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', nonce=71421764, timestamp=1572653293, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU+Rx7PbRe12ascscuo5C+ebnqXESIrA==', token_data=0)], parents=['4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=16, timestamp=1572653293.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', nonce=71421764, timestamp=1572653293, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU+Rx7PbRe12ascscuo5C+ebnqXESIrA==', token_data=0)], parents=['4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=17, timestamp=1572653294.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', nonce=2877639466, timestamp=1572653294, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUR/OZE3YnG5JNA94GMjCapu+YyqiIrA==', token_data=0)], parents=['b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=18, timestamp=1572653294.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', nonce=2877639466, timestamp=1572653294, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUR/OZE3YnG5JNA94GMjCapu+YyqiIrA==', token_data=0)], parents=['b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=19, timestamp=1572653295.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', nonce=1254860223, timestamp=1572653295, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU2G9W3JjDgfDf92m10Y1SliEnJWSIrA==', token_data=0)], parents=['c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=20, timestamp=1572653295.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', nonce=1254860223, timestamp=1572653295, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU2G9W3JjDgfDf92m10Y1SliEnJWSIrA==', token_data=0)], parents=['c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=21, timestamp=1572653296.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', nonce=681687539, timestamp=1572653296, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzWAOeu+SS7iMOMU3PLGJWw0pzeCIrA==', token_data=0)], parents=['429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=22, timestamp=1572653296.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', nonce=681687539, timestamp=1572653296, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzWAOeu+SS7iMOMU3PLGJWw0pzeCIrA==', token_data=0)], parents=['429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=23, timestamp=1572653297.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', nonce=1629369717, timestamp=1572653297, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUSQT96vTRhrFDCpyd3UYpXzzizO2IrA==', token_data=0)], parents=['81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=24, timestamp=1572653297.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', nonce=1629369717, timestamp=1572653297, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUSQT96vTRhrFDCpyd3UYpXzzizO2IrA==', token_data=0)], parents=['81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=25, timestamp=1572653298.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', nonce=1825990282, timestamp=1572653298, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU3ME2MVjVXosrj6JwB1CUW5YpRpyIrA==', token_data=0)], parents=['6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=26, timestamp=1572653298.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', nonce=1825990282, timestamp=1572653298, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU3ME2MVjVXosrj6JwB1CUW5YpRpyIrA==', token_data=0)], parents=['6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=27, timestamp=1572653299.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', nonce=738245143, timestamp=1572653299, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUuSgyjGBpztv2JOEZEuBZ8hMWj0yIrA==', token_data=0)], parents=['556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=28, timestamp=1572653299.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', nonce=738245143, timestamp=1572653299, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUuSgyjGBpztv2JOEZEuBZ8hMWj0yIrA==', token_data=0)], parents=['556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=29, timestamp=1572653349.5, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=6, previous_best_block='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', new_best_block='0016af90a6db3534d4c958ccb229e5abba279e79adc6199b08c2b7db96fa73da', common_block='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850'), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=30, timestamp=1572653349.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', nonce=1254860223, timestamp=1572653295, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU2G9W3JjDgfDf92m10Y1SliEnJWSIrA==', token_data=0)], parents=['c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', spent_outputs=[], conflict_with=[], voided_by=['429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac'], received_by=[], children=['81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full')), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=31, timestamp=1572653349.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', nonce=1825990282, timestamp=1572653298, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU3ME2MVjVXosrj6JwB1CUW5YpRpyIrA==', token_data=0)], parents=['6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', spent_outputs=[], conflict_with=[], voided_by=['556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e'], received_by=[], children=['ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full')), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=32, timestamp=1572653349.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', nonce=738245143, timestamp=1572653299, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUuSgyjGBpztv2JOEZEuBZ8hMWj0yIrA==', token_data=0)], parents=['556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', spent_outputs=[], conflict_with=[], voided_by=['ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full')), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=33, timestamp=1572653349.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0016af90a6db3534d4c958ccb229e5abba279e79adc6199b08c2b7db96fa73da', nonce=1240, timestamp=1572653349, version=0, weight=10.0, inputs=[], outputs=[TxOutput(value=6400, script='', token_data=0)], parents=['b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0016af90a6db3534d4c958ccb229e5abba279e79adc6199b08c2b7db96fa73da', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=10.044394119358454, first_block=None, height=6, validation='full')), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=34, timestamp=1572653349.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', nonce=2877639466, timestamp=1572653294, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUR/OZE3YnG5JNA94GMjCapu+YyqiIrA==', token_data=0)], parents=['b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', spent_outputs=[], conflict_with=[], voided_by=['c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e'], received_by=[], children=['429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full')), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=35, timestamp=1572653349.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', nonce=1629369717, timestamp=1572653297, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUSQT96vTRhrFDCpyd3UYpXzzizO2IrA==', token_data=0)], parents=['81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', spent_outputs=[], conflict_with=[], voided_by=['6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0'], received_by=[], children=['556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full')), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=36, timestamp=1572653349.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', nonce=681687539, timestamp=1572653296, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzWAOeu+SS7iMOMU3PLGJWw0pzeCIrA==', token_data=0)], parents=['429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', spent_outputs=[], conflict_with=[], voided_by=['81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db'], received_by=[], children=['6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full')), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=37, timestamp=1572653349.5, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=38, timestamp=1572653349.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0016af90a6db3534d4c958ccb229e5abba279e79adc6199b08c2b7db96fa73da', nonce=1240, timestamp=1572653349, version=0, weight=10.0, inputs=[], outputs=[TxOutput(value=6400, script='', token_data=0)], parents=['b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0016af90a6db3534d4c958ccb229e5abba279e79adc6199b08c2b7db96fa73da', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=10.044394119358454, first_block=None, height=6, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=39, timestamp=1572653409.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='22b18e265b261368cd67387eb0a226dddb56341551c326f5dd9120d3b715b475', nonce=2183063884, timestamp=1572653409, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUm3CeNv0dX1HsZAvl2H0Cr6NZ40CIrA==', token_data=0)], parents=['0016af90a6db3534d4c958ccb229e5abba279e79adc6199b08c2b7db96fa73da', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='22b18e265b261368cd67387eb0a226dddb56341551c326f5dd9120d3b715b475', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=10.049848549450562, first_block=None, height=7, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='fbcaa3d97704e1055be6eeb812befa1abcbe9074d778e5e071d5e18b4c4cec4d', id=40, timestamp=1572653409.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='22b18e265b261368cd67387eb0a226dddb56341551c326f5dd9120d3b715b475', nonce=2183063884, timestamp=1572653409, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUm3CeNv0dX1HsZAvl2H0Cr6NZ40CIrA==', token_data=0)], parents=['0016af90a6db3534d4c958ccb229e5abba279e79adc6199b08c2b7db96fa73da', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='22b18e265b261368cd67387eb0a226dddb56341551c326f5dd9120d3b715b475', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=10.049848549450562, first_block=None, height=7, validation='full')), group_id=None) # noqa E501 -] diff --git a/hathor/cli/events_simulator/scenarios/single_chain_blocks_and_transactions_events.py b/hathor/cli/events_simulator/scenarios/single_chain_blocks_and_transactions_events.py deleted file mode 100644 index 01bbccfdc..000000000 --- a/hathor/cli/events_simulator/scenarios/single_chain_blocks_and_transactions_events.py +++ /dev/null @@ -1,58 +0,0 @@ -# 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 hathor.event.model.base_event import BaseEvent, EventType -from hathor.event.model.event_data import EmptyData, SpentOutput, TxData, TxInput, TxMetadata, TxOutput - -SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS_EVENTS = [ - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=0, timestamp=1572653259.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=1, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=2, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=3, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=4, timestamp=1572653259.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=5, timestamp=1572653289.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2'], twins=[], accumulated_weight=2.0, score=2.0, first_block='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=6, timestamp=1572653289.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2'], twins=[], accumulated_weight=2.0, score=2.0, first_block='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=7, timestamp=1572653289.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', nonce=3849224008, timestamp=1572653289, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUCVEmDq3zPs6KV42QQDe7R/jVSsCIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=8, timestamp=1572653289.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', nonce=3849224008, timestamp=1572653289, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUCVEmDq3zPs6KV42QQDe7R/jVSsCIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=9, timestamp=1572653290.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', nonce=2571046484, timestamp=1572653290, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7TohZ0qkDwOGVvk902Ee5ocSLjiIrA==', token_data=0)], parents=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=10, timestamp=1572653290.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', nonce=2571046484, timestamp=1572653290, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7TohZ0qkDwOGVvk902Ee5ocSLjiIrA==', token_data=0)], parents=['d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=11, timestamp=1572653291.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', nonce=2810868913, timestamp=1572653291, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUJ1IwZftpI4amogcnKJWgc6/eJWuIrA==', token_data=0)], parents=['6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=12, timestamp=1572653291.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', nonce=2810868913, timestamp=1572653291, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUJ1IwZftpI4amogcnKJWgc6/eJWuIrA==', token_data=0)], parents=['6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=13, timestamp=1572653292.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', nonce=2900453906, timestamp=1572653292, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUA6/mkfdCoE0/VMGDn4pFDLOkJF6IrA==', token_data=0)], parents=['34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=14, timestamp=1572653292.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', nonce=2900453906, timestamp=1572653292, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUA6/mkfdCoE0/VMGDn4pFDLOkJF6IrA==', token_data=0)], parents=['34eb2302c10686be9755f4abc309ae6414dbd38a9a1b02c067f3b46f04def16c', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=15, timestamp=1572653293.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', nonce=71421764, timestamp=1572653293, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU+Rx7PbRe12ascscuo5C+ebnqXESIrA==', token_data=0)], parents=['4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=16, timestamp=1572653293.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', nonce=71421764, timestamp=1572653293, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU+Rx7PbRe12ascscuo5C+ebnqXESIrA==', token_data=0)], parents=['4f358aa26c3aec3ba29d67f7610d1efa01a71d82217c7f8cbfaf586ecaf46b4d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=17, timestamp=1572653294.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', nonce=2877639466, timestamp=1572653294, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUR/OZE3YnG5JNA94GMjCapu+YyqiIrA==', token_data=0)], parents=['b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=18, timestamp=1572653294.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', nonce=2877639466, timestamp=1572653294, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUR/OZE3YnG5JNA94GMjCapu+YyqiIrA==', token_data=0)], parents=['b9d8a77417f01e03ac13805c7d23f84367c72efb087aabaa8a6ce9669f407850', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=19, timestamp=1572653295.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', nonce=1254860223, timestamp=1572653295, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU2G9W3JjDgfDf92m10Y1SliEnJWSIrA==', token_data=0)], parents=['c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=20, timestamp=1572653295.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', nonce=1254860223, timestamp=1572653295, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU2G9W3JjDgfDf92m10Y1SliEnJWSIrA==', token_data=0)], parents=['c9066a952b25ff994461c39f16665602ee8b9d13da143307d264612d7e408d1e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=21, timestamp=1572653296.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', nonce=681687539, timestamp=1572653296, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzWAOeu+SS7iMOMU3PLGJWw0pzeCIrA==', token_data=0)], parents=['429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=22, timestamp=1572653296.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', nonce=681687539, timestamp=1572653296, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzWAOeu+SS7iMOMU3PLGJWw0pzeCIrA==', token_data=0)], parents=['429543a84d186b6d3e6e20c41bfc6b26c812a18e04cc03deebf2d8ba05780aac', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=23, timestamp=1572653297.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', nonce=1629369717, timestamp=1572653297, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUSQT96vTRhrFDCpyd3UYpXzzizO2IrA==', token_data=0)], parents=['81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=24, timestamp=1572653297.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', nonce=1629369717, timestamp=1572653297, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUSQT96vTRhrFDCpyd3UYpXzzizO2IrA==', token_data=0)], parents=['81e7e7d0b7fb462a2d56d3df26327d9668679b447db9bbc7dd76d2ec9e5970db', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=25, timestamp=1572653298.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', nonce=1825990282, timestamp=1572653298, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU3ME2MVjVXosrj6JwB1CUW5YpRpyIrA==', token_data=0)], parents=['6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=26, timestamp=1572653298.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', nonce=1825990282, timestamp=1572653298, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU3ME2MVjVXosrj6JwB1CUW5YpRpyIrA==', token_data=0)], parents=['6a04d02f03caecd8d9a5c5388fc15afd1022b2db13f68e79f7a4568ac30329d0', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=27, timestamp=1572653299.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', nonce=738245143, timestamp=1572653299, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUuSgyjGBpztv2JOEZEuBZ8hMWj0yIrA==', token_data=0)], parents=['556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=28, timestamp=1572653299.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', nonce=738245143, timestamp=1572653299, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUuSgyjGBpztv2JOEZEuBZ8hMWj0yIrA==', token_data=0)], parents=['556f8669c2c5beb864e2f0b34090bd86dcd4922dc6ccef8108bc4ba69b785e9e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=29, timestamp=1572653370.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', nonce=3849224008, timestamp=1572653289, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUCVEmDq3zPs6KV42QQDe7R/jVSsCIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', spent_outputs=[SpentOutput(index=0, tx_ids=['f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79'])], conflict_with=[], voided_by=[], received_by=[], children=['6c4babf9e8fcda5c2eb9628cdef0216e9ac5ae6c118c671deb29ad705e0751b1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=30, timestamp=1572653370.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', nonce=2, timestamp=1572653369, version=1, weight=18.664694903964126, inputs=[TxInput(tx_id='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', index=0, data='SDBGAiEAwRECSYXApimxuQ9cD88w9U0N+SdAtJZfi0x1e3VgGmYCIQDsIsEC2nZzWgIa1U+eh/pIzhMg0rKvH3u8BaRLCpz4ICEC6Y5mbQB/qe5dH40iULOaEGoGq9CKeQMumnT8+yyMIHM=')], outputs=[TxOutput(value=1431, script='dqkU91U6sMdzgT3zxOtdIVGbqobP0FmIrA==', token_data=0), TxOutput(value=4969, script='dqkUm3CeNv0dX1HsZAvl2H0Cr6NZ40CIrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.664694903964126, score=0.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=31, timestamp=1572653370.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', nonce=2, timestamp=1572653369, version=1, weight=18.664694903964126, inputs=[TxInput(tx_id='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', index=0, data='SDBGAiEAwRECSYXApimxuQ9cD88w9U0N+SdAtJZfi0x1e3VgGmYCIQDsIsEC2nZzWgIa1U+eh/pIzhMg0rKvH3u8BaRLCpz4ICEC6Y5mbQB/qe5dH40iULOaEGoGq9CKeQMumnT8+yyMIHM=')], outputs=[TxOutput(value=1431, script='dqkU91U6sMdzgT3zxOtdIVGbqobP0FmIrA==', token_data=0), TxOutput(value=4969, script='dqkUm3CeNv0dX1HsZAvl2H0Cr6NZ40CIrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.664694903964126, score=0.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=32, timestamp=1572653384.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', nonce=4, timestamp=1572653384, version=1, weight=19.568795613217652, inputs=[TxInput(tx_id='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', index=0, data='RzBFAiBYhxr1IwcaECRZ+1aBbbribFNlBwaHj6xYloRvM5GgNgIhAJEZFLLmhQu50PkbVN+ShY0Wu3nC8ovnH/0A4HPT+oM3IQJ5e3XMPtNc1G7jFBLtvi0UahT3TdEIE7Oy5aV8FTNzng=='), TxInput(tx_id='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', index=1, data='RzBFAiBpIjqEJTn35NZ6f5K1yjKhs+JI52VaeoVYeh/KKXVCaQIhAPFpz7OuVHxAjY47dUqf30WAK/K65ESfwFcc3cq8Vx5QIQNuTU0Ido94RX5qWDgmtAgJIgBn2levBgXDiFai9kRQpg==')], outputs=[TxOutput(value=1199, script='dqkULLHzgtmv69PpRwlTBTzNGRcIE9yIrA==', token_data=0), TxOutput(value=5201, script='dqkUhLDX6YydV5HBbevVaHD+YWuBHRyIrA==', token_data=0)], parents=['f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=19.568795613217652, score=0.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=33, timestamp=1572653384.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', nonce=2, timestamp=1572653369, version=1, weight=18.664694903964126, inputs=[TxInput(tx_id='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', index=0, data='SDBGAiEAwRECSYXApimxuQ9cD88w9U0N+SdAtJZfi0x1e3VgGmYCIQDsIsEC2nZzWgIa1U+eh/pIzhMg0rKvH3u8BaRLCpz4ICEC6Y5mbQB/qe5dH40iULOaEGoGq9CKeQMumnT8+yyMIHM=')], outputs=[TxOutput(value=1431, script='dqkU91U6sMdzgT3zxOtdIVGbqobP0FmIrA==', token_data=0), TxOutput(value=4969, script='dqkUm3CeNv0dX1HsZAvl2H0Cr6NZ40CIrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', spent_outputs=[SpentOutput(index=0, tx_ids=['58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f']), SpentOutput(index=1, tx_ids=['58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f'])], conflict_with=[], voided_by=[], received_by=[], children=['58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f'], twins=[], accumulated_weight=18.664694903964126, score=0.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=34, timestamp=1572653384.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', nonce=4, timestamp=1572653384, version=1, weight=19.568795613217652, inputs=[TxInput(tx_id='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', index=0, data='RzBFAiBYhxr1IwcaECRZ+1aBbbribFNlBwaHj6xYloRvM5GgNgIhAJEZFLLmhQu50PkbVN+ShY0Wu3nC8ovnH/0A4HPT+oM3IQJ5e3XMPtNc1G7jFBLtvi0UahT3TdEIE7Oy5aV8FTNzng=='), TxInput(tx_id='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', index=1, data='RzBFAiBpIjqEJTn35NZ6f5K1yjKhs+JI52VaeoVYeh/KKXVCaQIhAPFpz7OuVHxAjY47dUqf30WAK/K65ESfwFcc3cq8Vx5QIQNuTU0Ido94RX5qWDgmtAgJIgBn2levBgXDiFai9kRQpg==')], outputs=[TxOutput(value=1199, script='dqkULLHzgtmv69PpRwlTBTzNGRcIE9yIrA==', token_data=0), TxOutput(value=5201, script='dqkUhLDX6YydV5HBbevVaHD+YWuBHRyIrA==', token_data=0)], parents=['f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=19.568795613217652, score=0.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=35, timestamp=1572653409.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', nonce=4, timestamp=1572653384, version=1, weight=19.568795613217652, inputs=[TxInput(tx_id='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', index=0, data='RzBFAiBYhxr1IwcaECRZ+1aBbbribFNlBwaHj6xYloRvM5GgNgIhAJEZFLLmhQu50PkbVN+ShY0Wu3nC8ovnH/0A4HPT+oM3IQJ5e3XMPtNc1G7jFBLtvi0UahT3TdEIE7Oy5aV8FTNzng=='), TxInput(tx_id='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', index=1, data='RzBFAiBpIjqEJTn35NZ6f5K1yjKhs+JI52VaeoVYeh/KKXVCaQIhAPFpz7OuVHxAjY47dUqf30WAK/K65ESfwFcc3cq8Vx5QIQNuTU0Ido94RX5qWDgmtAgJIgBn2levBgXDiFai9kRQpg==')], outputs=[TxOutput(value=1199, script='dqkULLHzgtmv69PpRwlTBTzNGRcIE9yIrA==', token_data=0), TxOutput(value=5201, script='dqkUhLDX6YydV5HBbevVaHD+YWuBHRyIrA==', token_data=0)], parents=['f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa'], twins=[], accumulated_weight=19.568795613217652, score=0.0, first_block='01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=36, timestamp=1572653409.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa', nonce=4226205465, timestamp=1572653409, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUlAsOm11At4ng3JBW477DOP0eQtGIrA==', token_data=0)], parents=['ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', '58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', 'f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=20.18681516127742, first_block=None, height=12, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=37, timestamp=1572653409.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', nonce=2, timestamp=1572653369, version=1, weight=18.664694903964126, inputs=[TxInput(tx_id='d8d221392cda50bdb2c4bef1f11f826ddcad85ddab395d062d05fc4a592195c2', index=0, data='SDBGAiEAwRECSYXApimxuQ9cD88w9U0N+SdAtJZfi0x1e3VgGmYCIQDsIsEC2nZzWgIa1U+eh/pIzhMg0rKvH3u8BaRLCpz4ICEC6Y5mbQB/qe5dH40iULOaEGoGq9CKeQMumnT8+yyMIHM=')], outputs=[TxOutput(value=1431, script='dqkU91U6sMdzgT3zxOtdIVGbqobP0FmIrA==', token_data=0), TxOutput(value=4969, script='dqkUm3CeNv0dX1HsZAvl2H0Cr6NZ40CIrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79', spent_outputs=[SpentOutput(index=0, tx_ids=['58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f']), SpentOutput(index=1, tx_ids=['58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f'])], conflict_with=[], voided_by=[], received_by=[], children=['58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', '01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa'], twins=[], accumulated_weight=18.664694903964126, score=0.0, first_block='01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='bdf4fa876f5cdba84be0cab53b21fc9eb45fe4b3d6ede99f493119d37df4e560', id=38, timestamp=1572653409.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa', nonce=4226205465, timestamp=1572653409, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUlAsOm11At4ng3JBW477DOP0eQtGIrA==', token_data=0)], parents=['ddf62cc80ce6aa1a64fe89b5d15af59555e94126f88618eb28fae6a5b51fcae6', '58fba3126e91f546fc11792637d0c4112e2de12920628f98ca1abe4fa97cc74f', 'f42fbcd1549389632236f85a80ad2dd8cac2f150501fb40b11210bad03718f79'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='01375179ce0f6a6d6501fec0ee14dba8e134372a8fe6519aa952ced7b0577aaa', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=20.18681516127742, first_block=None, height=12, validation='full')), group_id=None) # noqa E501 -] diff --git a/hathor/cli/events_simulator/scenarios/single_chain_one_block_events.py b/hathor/cli/events_simulator/scenarios/single_chain_one_block_events.py deleted file mode 100644 index 47094106e..000000000 --- a/hathor/cli/events_simulator/scenarios/single_chain_one_block_events.py +++ /dev/null @@ -1,28 +0,0 @@ -# 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 hathor.event.model.base_event import BaseEvent, EventType -from hathor.event.model.event_data import EmptyData, TxData, TxMetadata, TxOutput - -SINGLE_CHAIN_ONE_BLOCK_EVENTS = [ - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=0, timestamp=1572653259.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=1, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=2, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=3, timestamp=1572653259.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=4, timestamp=1572653259.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=5, timestamp=1572653409.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8', nonce=3849224008, timestamp=1572653409, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUCVEmDq3zPs6KV42QQDe7R/jVSsCIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=6, timestamp=1572653409.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8'], twins=[], accumulated_weight=2.0, score=2.0, first_block='c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=7, timestamp=1572653409.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8'], twins=[], accumulated_weight=2.0, score=2.0, first_block='c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8', height=0, validation='full')), group_id=None), # noqa E501 - BaseEvent(peer_id='30035f10e02f83ec585bf3ab9e8f41ec905d11a06fdca737be28dfa919e14d26', id=8, timestamp=1572653409.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8', nonce=3849224008, timestamp=1572653409, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUCVEmDq3zPs6KV42QQDe7R/jVSsCIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='c7316accecf14910349ee06dbc265d7daa87cfb65c36b317f0985cb75ec71de8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full')), group_id=None) # noqa E501 -] diff --git a/tests/event/test_event_simulation_scenarios.py b/tests/event/test_event_simulation_scenarios.py index d673042b6..37ce4ccea 100644 --- a/tests/event/test_event_simulation_scenarios.py +++ b/tests/event/test_event_simulation_scenarios.py @@ -12,14 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +from hathor.cli.events_simulator.scenario import Scenario from hathor.event.model.base_event import BaseEvent from hathor.event.model.event_data import EmptyData, ReorgData, SpentOutput, TxData, TxInput, TxMetadata, TxOutput from hathor.event.model.event_type import EventType from hathor.event.websocket.request import StartStreamRequest from hathor.event.websocket.response import EventResponse -from hathor.p2p.peer_id import PeerId -from hathor.simulator import FakeConnection -from hathor.simulator.trigger import StopAfterNMinedBlocks, StopAfterNTransactions from tests.event.event_simulation_tester import ( BaseEventSimulationTester, MemoryEventSimulationTester, @@ -36,9 +34,8 @@ class BaseEventSimulationScenariosTest(BaseEventSimulationTester): seed_config = 6946502462188444706 def test_only_load(self) -> None: - start_stream = StartStreamRequest(type='START_STREAM', window_size=1_000_000, last_ack_event_id=None) - self._send_request(start_stream) - self.simulator.run(3600) + Scenario.ONLY_LOAD.simulate(self.simulator, self.manager) + self._start_stream() responses = self._get_success_responses() @@ -56,16 +53,8 @@ def test_only_load(self) -> None: assert responses == expected, f'expected: {expected}\n\nactual: {responses}' def test_single_chain_one_block(self): - miner = self.simulator.create_miner(self.manager, hashpower=1e6) - miner.start() - - trigger = StopAfterNMinedBlocks(miner, quantity=1) - self.simulator.run(3600, trigger=trigger) - miner.stop() - - start_stream = StartStreamRequest(type='START_STREAM', window_size=1_000_000, last_ack_event_id=None) - self._send_request(start_stream) - self.simulator.run(3600) + Scenario.SINGLE_CHAIN_ONE_BLOCK.simulate(self.simulator, self.manager) + self._start_stream() responses = self._get_success_responses() @@ -79,120 +68,80 @@ def test_single_chain_one_block(self): # LOAD_FINISHED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=8), # noqa E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360'], twins=[], accumulated_weight=2.0, score=2.0, first_block='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360'], twins=[], accumulated_weight=2.0, score=2.0, first_block='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', nonce=105631935, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', nonce=105631935, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8) # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8) # noqa E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' def test_single_chain_blocks_and_transactions(self): - miner = self.simulator.create_miner(self.manager, hashpower=1e6) - tx_gen = self.simulator.create_tx_generator(self.manager, rate=3 / 60, hashpower=1e6, ignore_no_funds=True) - - miner_trigger = StopAfterNMinedBlocks(miner, quantity=11) - miner.start() - self.simulator.run(3600, trigger=miner_trigger) - miner.stop() - - tx_trigger = StopAfterNTransactions(tx_gen, quantity=2) - tx_gen.start() - self.simulator.run(3600, trigger=tx_trigger) - tx_gen.stop() - - miner_trigger = StopAfterNMinedBlocks(miner, quantity=1) - miner.start() - self.simulator.run(3600, trigger=miner_trigger) - miner.stop() - - self.simulator.run(3600) - start_stream = StartStreamRequest(type='START_STREAM', window_size=1_000_000, last_ack_event_id=None) - self._send_request(start_stream) - self.simulator.run(3600) + Scenario.SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS.simulate(self.simulator, self.manager) + self._start_stream() responses = self._get_success_responses() expected = [ # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=36), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=36), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360'], twins=[], accumulated_weight=2.0, score=2.0, first_block='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360'], twins=[], accumulated_weight=2.0, score=2.0, first_block='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', nonce=105631935, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', nonce=105631935, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 # One VERTEX_METADATA_CHANGED and one NEW_VERTEX_ACCEPTED for 10 new blocks - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578878910.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='967f7d6577e5b301d7facaf7fecd87f18586acfd24fc52e49251c9c4195b49f6', nonce=1279407725, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', token_data=0)], parents=['53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='967f7d6577e5b301d7facaf7fecd87f18586acfd24fc52e49251c9c4195b49f6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578878910.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='967f7d6577e5b301d7facaf7fecd87f18586acfd24fc52e49251c9c4195b49f6', nonce=1279407725, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', token_data=0)], parents=['53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='967f7d6577e5b301d7facaf7fecd87f18586acfd24fc52e49251c9c4195b49f6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578878910.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='68585cc41a0cc261e97e5cf9d035e4950a9897b9fba18cbec194824522c03c7b', nonce=1529920189, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', token_data=0)], parents=['967f7d6577e5b301d7facaf7fecd87f18586acfd24fc52e49251c9c4195b49f6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='68585cc41a0cc261e97e5cf9d035e4950a9897b9fba18cbec194824522c03c7b', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578878910.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='68585cc41a0cc261e97e5cf9d035e4950a9897b9fba18cbec194824522c03c7b', nonce=1529920189, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', token_data=0)], parents=['967f7d6577e5b301d7facaf7fecd87f18586acfd24fc52e49251c9c4195b49f6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='68585cc41a0cc261e97e5cf9d035e4950a9897b9fba18cbec194824522c03c7b', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578878911.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0ed0c5540b258485199d1938646bcf10fc3b086da1110af41806c6d0792f413e', nonce=1828786391, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', token_data=0)], parents=['68585cc41a0cc261e97e5cf9d035e4950a9897b9fba18cbec194824522c03c7b', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0ed0c5540b258485199d1938646bcf10fc3b086da1110af41806c6d0792f413e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578878911.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0ed0c5540b258485199d1938646bcf10fc3b086da1110af41806c6d0792f413e', nonce=1828786391, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', token_data=0)], parents=['68585cc41a0cc261e97e5cf9d035e4950a9897b9fba18cbec194824522c03c7b', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0ed0c5540b258485199d1938646bcf10fc3b086da1110af41806c6d0792f413e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578878911.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='79c4da1aa12adbb3e384f3e631cf0f8898922db6a7a157c878d6dd5d27b62e77', nonce=1915673046, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', token_data=0)], parents=['0ed0c5540b258485199d1938646bcf10fc3b086da1110af41806c6d0792f413e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='79c4da1aa12adbb3e384f3e631cf0f8898922db6a7a157c878d6dd5d27b62e77', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578878911.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='79c4da1aa12adbb3e384f3e631cf0f8898922db6a7a157c878d6dd5d27b62e77', nonce=1915673046, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', token_data=0)], parents=['0ed0c5540b258485199d1938646bcf10fc3b086da1110af41806c6d0792f413e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='79c4da1aa12adbb3e384f3e631cf0f8898922db6a7a157c878d6dd5d27b62e77', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578878911.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0c88949d8b9eef81bf0896aabe875c4bd1172bc834b7bc4cc1c756a3d243ec52', nonce=1279525218, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', token_data=0)], parents=['79c4da1aa12adbb3e384f3e631cf0f8898922db6a7a157c878d6dd5d27b62e77', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0c88949d8b9eef81bf0896aabe875c4bd1172bc834b7bc4cc1c756a3d243ec52', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578878911.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0c88949d8b9eef81bf0896aabe875c4bd1172bc834b7bc4cc1c756a3d243ec52', nonce=1279525218, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', token_data=0)], parents=['79c4da1aa12adbb3e384f3e631cf0f8898922db6a7a157c878d6dd5d27b62e77', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0c88949d8b9eef81bf0896aabe875c4bd1172bc834b7bc4cc1c756a3d243ec52', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578878911.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='3624a05261b604d4ff46b0157892b2ff48a7fb1e31fe65e58fbbfe88cadcbdd4', nonce=4136633663, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', token_data=0)], parents=['0c88949d8b9eef81bf0896aabe875c4bd1172bc834b7bc4cc1c756a3d243ec52', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='3624a05261b604d4ff46b0157892b2ff48a7fb1e31fe65e58fbbfe88cadcbdd4', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578878911.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='3624a05261b604d4ff46b0157892b2ff48a7fb1e31fe65e58fbbfe88cadcbdd4', nonce=4136633663, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', token_data=0)], parents=['0c88949d8b9eef81bf0896aabe875c4bd1172bc834b7bc4cc1c756a3d243ec52', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='3624a05261b604d4ff46b0157892b2ff48a7fb1e31fe65e58fbbfe88cadcbdd4', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=21, timestamp=1578878912.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='282d65827ecc485b1c8b916f71605da0f15f353325feb9a1a87fe320c1ebc915', nonce=945260546, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', token_data=0)], parents=['3624a05261b604d4ff46b0157892b2ff48a7fb1e31fe65e58fbbfe88cadcbdd4', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='282d65827ecc485b1c8b916f71605da0f15f353325feb9a1a87fe320c1ebc915', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=22, timestamp=1578878912.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='282d65827ecc485b1c8b916f71605da0f15f353325feb9a1a87fe320c1ebc915', nonce=945260546, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', token_data=0)], parents=['3624a05261b604d4ff46b0157892b2ff48a7fb1e31fe65e58fbbfe88cadcbdd4', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='282d65827ecc485b1c8b916f71605da0f15f353325feb9a1a87fe320c1ebc915', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=23, timestamp=1578878912.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='4978ebbeb98dccae64f3d32269e1a1030892c82b023448cafd649cad73e9127a', nonce=2222918728, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', token_data=0)], parents=['282d65827ecc485b1c8b916f71605da0f15f353325feb9a1a87fe320c1ebc915', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4978ebbeb98dccae64f3d32269e1a1030892c82b023448cafd649cad73e9127a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=24, timestamp=1578878912.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='4978ebbeb98dccae64f3d32269e1a1030892c82b023448cafd649cad73e9127a', nonce=2222918728, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', token_data=0)], parents=['282d65827ecc485b1c8b916f71605da0f15f353325feb9a1a87fe320c1ebc915', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4978ebbeb98dccae64f3d32269e1a1030892c82b023448cafd649cad73e9127a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=25, timestamp=1578878912.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='47ced60615a9d5d4fc1ca26d9dbc71ca89b8b35541b31d8e75a65d4badfa99c7', nonce=3090209358, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', token_data=0)], parents=['4978ebbeb98dccae64f3d32269e1a1030892c82b023448cafd649cad73e9127a', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='47ced60615a9d5d4fc1ca26d9dbc71ca89b8b35541b31d8e75a65d4badfa99c7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=26, timestamp=1578878912.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='47ced60615a9d5d4fc1ca26d9dbc71ca89b8b35541b31d8e75a65d4badfa99c7', nonce=3090209358, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', token_data=0)], parents=['4978ebbeb98dccae64f3d32269e1a1030892c82b023448cafd649cad73e9127a', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='47ced60615a9d5d4fc1ca26d9dbc71ca89b8b35541b31d8e75a65d4badfa99c7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=27, timestamp=1578878912.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='15599c25cb30892add963558e06c97c2a838a8a5c047aee416dc9a3617d59baa', nonce=3024981275, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', token_data=0)], parents=['47ced60615a9d5d4fc1ca26d9dbc71ca89b8b35541b31d8e75a65d4badfa99c7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='15599c25cb30892add963558e06c97c2a838a8a5c047aee416dc9a3617d59baa', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=28, timestamp=1578878912.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='15599c25cb30892add963558e06c97c2a838a8a5c047aee416dc9a3617d59baa', nonce=3024981275, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', token_data=0)], parents=['47ced60615a9d5d4fc1ca26d9dbc71ca89b8b35541b31d8e75a65d4badfa99c7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='15599c25cb30892add963558e06c97c2a838a8a5c047aee416dc9a3617d59baa', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', token_data=0)], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', token_data=0)], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', token_data=0)], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', token_data=0)], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', token_data=0)], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', token_data=0)], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', token_data=0)], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', token_data=0)], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', token_data=0)], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', token_data=0)], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', token_data=0)], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', token_data=0)], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=21, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', token_data=0)], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=22, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', token_data=0)], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=23, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', token_data=0)], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=24, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', token_data=0)], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=25, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', token_data=0)], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=26, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', token_data=0)], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=27, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', token_data=0)], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=28, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', token_data=0)], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a block, adding the new tx as spending their output # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=29, timestamp=1578879395.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', nonce=105631935, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', spent_outputs=[SpentOutput(index=0, tx_ids=['bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c'])], conflict_with=[], voided_by=[], received_by=[], children=['967f7d6577e5b301d7facaf7fecd87f18586acfd24fc52e49251c9c4195b49f6'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=30, timestamp=1578879395.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', nonce=0, timestamp=1578879395, version=1, weight=18.648830153779993, inputs=[TxInput(tx_id='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', index=0, data='RjBEAiBQAVgs/jYpndowN3/JMI07fM886ergyyGA2xXaHCu5BQIgf58pdc8S9ABgzkUx8qDQUtV3FcYCMMzHs90q36L0J+whA0zN7LEgxcswPkHbbW7mdnkS5yviaZFgjID1mhpSZSQf')], outputs=[TxOutput(value=2132, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=4268, script='dqkUBvl1aaAtzoh8a9vaZoqXA6JxK4OIrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.648830153779993, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=29, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=30, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[SpentOutput(index=0, tx_ids=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'])], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 # One NEW_VERTEX_ACCEPTED for a new tx - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=31, timestamp=1578879395.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', nonce=0, timestamp=1578879395, version=1, weight=18.648830153779993, inputs=[TxInput(tx_id='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', index=0, data='RjBEAiBQAVgs/jYpndowN3/JMI07fM886ergyyGA2xXaHCu5BQIgf58pdc8S9ABgzkUx8qDQUtV3FcYCMMzHs90q36L0J+whA0zN7LEgxcswPkHbbW7mdnkS5yviaZFgjID1mhpSZSQf')], outputs=[TxOutput(value=2132, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=4268, script='dqkUBvl1aaAtzoh8a9vaZoqXA6JxK4OIrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.648830153779993, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a block, adding the new tx as spending their output # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879429.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='47b26240891fb57320d72cbd708f5287ca056e73f4b19bb295e6b19d984c07ea', nonce=0, timestamp=1578879423, version=1, weight=19.563446104298656, inputs=[TxInput(tx_id='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', index=0, data='RzBFAiANP0tUHsWIPFnkwG0Io7W53viGaXgWfyniIsyJHIva7AIhAIij02z4JPki4RT5b/UkJoKVgazA7QWIq1Zwvik2xhXZIQOnBXShvpioJZgNxYy4lgCg4o84Uw9ncOQuv9mxPWEqeg=='), TxInput(tx_id='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', index=1, data='RjBEAiAj6I8PifTvE1J7eAqxHLu2YqFThzc4C4YzIzq+aX1fBQIgdH+xu08lWjdGiRjuaYgf/S9EZYw8U1HJQ2//WtERx9chA9euCC5MDnVV3I2e5yKj1Q65BsqgN2+IwojZqatIF3T8')], outputs=[TxOutput(value=2764, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=3636, script='dqkUFgE9a6rVMusN303z18sYfjdpYGqIrA==', token_data=0)], parents=['bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='47b26240891fb57320d72cbd708f5287ca056e73f4b19bb295e6b19d984c07ea', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=19.563446104298656, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879429.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', nonce=0, timestamp=1578879395, version=1, weight=18.648830153779993, inputs=[TxInput(tx_id='53c5fe57a6d79ab4a8eca660bd0a9935fe9f82d2506d80e0c48339c42c234360', index=0, data='RjBEAiBQAVgs/jYpndowN3/JMI07fM886ergyyGA2xXaHCu5BQIgf58pdc8S9ABgzkUx8qDQUtV3FcYCMMzHs90q36L0J+whA0zN7LEgxcswPkHbbW7mdnkS5yviaZFgjID1mhpSZSQf')], outputs=[TxOutput(value=2132, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=4268, script='dqkUBvl1aaAtzoh8a9vaZoqXA6JxK4OIrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', spent_outputs=[SpentOutput(index=0, tx_ids=['47b26240891fb57320d72cbd708f5287ca056e73f4b19bb295e6b19d984c07ea']), SpentOutput(index=1, tx_ids=['47b26240891fb57320d72cbd708f5287ca056e73f4b19bb295e6b19d984c07ea'])], conflict_with=[], voided_by=[], received_by=[], children=['47b26240891fb57320d72cbd708f5287ca056e73f4b19bb295e6b19d984c07ea'], twins=[], accumulated_weight=18.648830153779993, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=31, timestamp=1578878970.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a tx, adding the new tx as spending their output and children # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, data='RjBEAiAYv9mzh3RMOpZvHEWgNIvBIdlkUGXK14v5fMf9kH8GkAIgcAld8/EAJuJ7YPnUy1LiUElgvhHnz5cH8zacyGj2B7YhA6cFdKG+mKglmA3FjLiWAKDijzhTD2dw5C6/2bE9YSp6')], outputs=[TxOutput(value=3400, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=2000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 # One NEW_VERTEX_ACCEPTED for a new tx - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879429.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='47b26240891fb57320d72cbd708f5287ca056e73f4b19bb295e6b19d984c07ea', nonce=0, timestamp=1578879423, version=1, weight=19.563446104298656, inputs=[TxInput(tx_id='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', index=0, data='RzBFAiANP0tUHsWIPFnkwG0Io7W53viGaXgWfyniIsyJHIva7AIhAIij02z4JPki4RT5b/UkJoKVgazA7QWIq1Zwvik2xhXZIQOnBXShvpioJZgNxYy4lgCg4o84Uw9ncOQuv9mxPWEqeg=='), TxInput(tx_id='bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', index=1, data='RjBEAiAj6I8PifTvE1J7eAqxHLu2YqFThzc4C4YzIzq+aX1fBQIgdH+xu08lWjdGiRjuaYgf/S9EZYw8U1HJQ2//WtERx9chA9euCC5MDnVV3I2e5yKj1Q65BsqgN2+IwojZqatIF3T8')], outputs=[TxOutput(value=2764, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=3636, script='dqkUFgE9a6rVMusN303z18sYfjdpYGqIrA==', token_data=0)], parents=['bd1c5ae097470eecfe10b3f25e02c0f8358b95706484b2174c6ea0ff930cc25c', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='47b26240891fb57320d72cbd708f5287ca056e73f4b19bb295e6b19d984c07ea', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=19.563446104298656, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - # One VERTEX_METADATA_CHANGED and one NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879429.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f2d1327e556ac534e0d934c4e884af3ffe5ecdfd7c5045e30a123a8171500990', nonce=2907562093, timestamp=1578878921, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUBvl1aaAtzoh8a9vaZoqXA6JxK4OIrA==', token_data=0)], parents=['15599c25cb30892add963558e06c97c2a838a8a5c047aee416dc9a3617d59baa', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f2d1327e556ac534e0d934c4e884af3ffe5ecdfd7c5045e30a123a8171500990', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=8.285402218862249, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=36), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879429.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='f2d1327e556ac534e0d934c4e884af3ffe5ecdfd7c5045e30a123a8171500990', nonce=2907562093, timestamp=1578878921, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUBvl1aaAtzoh8a9vaZoqXA6JxK4OIrA==', token_data=0)], parents=['15599c25cb30892add963558e06c97c2a838a8a5c047aee416dc9a3617d59baa', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f2d1327e556ac534e0d934c4e884af3ffe5ecdfd7c5045e30a123a8171500990', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=8.285402218862249, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=36) # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879030.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, data='RjBEAiAYv9mzh3RMOpZvHEWgNIvBIdlkUGXK14v5fMf9kH8GkAIgcAld8/EAJuJ7YPnUy1LiUElgvhHnz5cH8zacyGj2B7YhA6cFdKG+mKglmA3FjLiWAKDijzhTD2dw5C6/2bE9YSp6')], outputs=[TxOutput(value=3400, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=2000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each confirmed transaction # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', token_data=0)], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=37, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, data='RjBEAiAYv9mzh3RMOpZvHEWgNIvBIdlkUGXK14v5fMf9kH8GkAIgcAld8/EAJuJ7YPnUy1LiUElgvhHnz5cH8zacyGj2B7YhA6cFdKG+mKglmA3FjLiWAKDijzhTD2dw5C6/2bE9YSp6')], outputs=[TxOutput(value=3400, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=2000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + # One NEW_VERTEX_ACCEPTED for a new block + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=38, timestamp=1578879091.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', token_data=0)], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38) # noqa E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' def test_reorg(self): - miner1 = self.simulator.create_miner(self.manager, hashpower=1e6) - - builder = self.simulator.get_default_builder().set_peer_id(PeerId()) - manager2 = self.simulator.create_peer(builder) - manager2.allow_mining_without_peers() - - miner2 = self.simulator.create_miner(manager2, hashpower=1e6) - - connection = FakeConnection(self.manager, manager2, latency=1) - self.simulator.add_connection(connection) - - trigger1 = StopAfterNMinedBlocks(miner1, quantity=1) - miner1.start() - self.simulator.run(3600, trigger=trigger1) - miner1.stop() - - trigger2 = StopAfterNMinedBlocks(miner2, quantity=2) - miner2.start() - self.simulator.run(3600, trigger=trigger2) - miner2.stop() - - self.simulator.run(3600) - start_stream = StartStreamRequest(type='START_STREAM', window_size=1_000_000, last_ack_event_id=None) - self._send_request(start_stream) - self.simulator.run(3600) + Scenario.REORG.simulate(self.simulator, self.manager) + self._start_stream() responses = self._get_success_responses() @@ -200,41 +149,46 @@ def test_reorg(self): # LOAD_STATED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 # LOAD_FINISHED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3'], twins=[], accumulated_weight=2.0, score=2.0, first_block='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3'], twins=[], accumulated_weight=2.0, score=2.0, first_block='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', nonce=2246536493, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 # One NEW_VERTEX_ACCEPTED for a new block from manager1 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878940.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', nonce=2246536493, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878940.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 # Also one VERTEX_METADATA_CHANGED for the previous block, voiding it - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578878949.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', '4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578878949.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', '4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578878949.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', nonce=2246536493, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', spent_outputs=[], conflict_with=[], voided_by=['3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578878949.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', nonce=1279525218, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', spent_outputs=[], conflict_with=[], voided_by=['4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578878949.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', nonce=1279525218, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', spent_outputs=[], conflict_with=[], voided_by=['4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578879064.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 # REORG_STARTED caused by a new block from manager2 (below) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578878950.0, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=1, previous_best_block='3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', new_best_block='a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4', common_block='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792'), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578879064.25, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=1, previous_best_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', new_best_block='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', common_block='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792'), group_id=0), latest_event_id=20), # noqa E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 # Also one VERTEX_METADATA_CHANGED for the previous block, un-voiding it as it's now part of the best blockchain # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578878950.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', '4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', 'a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4'], twins=[], accumulated_weight=2.0, score=2.0, first_block='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578878950.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['3cfde60f140d2838581d885e656af1049fa8eab964defc5bca3d883b83c9afc3', '4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', 'a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4'], twins=[], accumulated_weight=2.0, score=2.0, first_block='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578878950.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', nonce=1279525218, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578878950.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4', nonce=4136633663, timestamp=1578878941, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', token_data=0)], parents=['4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', token_data=0)], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 # REORG_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578878950.0, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578879064.25, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), latest_event_id=20), # noqa E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578878950.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4', nonce=4136633663, timestamp=1578878941, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', token_data=0)], parents=['4f0b3d13966f95f461d4edc6389c8440955e13a75f87c6bc2a4b455d813fb2f7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='a729a7abb4248dffa492dd2c2634aa6d92b3e1e05bfa6614118b6ba97bfba5c4', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=20) # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578879064.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', token_data=0)], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=20) # noqa E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' + def _start_stream(self) -> None: + start_stream = StartStreamRequest(type='START_STREAM', window_size=1_000_000, last_ack_event_id=None) + self._send_request(start_stream) + self.simulator.run(60) + class MemoryEventSimulationScenariosTest(BaseEventSimulationScenariosTest, MemoryEventSimulationTester): __test__ = True From 0f78923b5939396cb830c6029b510033daffdf84 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Sun, 10 Sep 2023 22:17:09 -0300 Subject: [PATCH 02/26] feat(reliable-integration): add decoded outputs in event responses (#763) --- hathor/event/model/event_data.py | 37 +++- hathor/transaction/resources/transaction.py | 27 +-- tests/event/test_event_reorg.py | 4 +- .../event/test_event_simulation_scenarios.py | 166 +++++++++--------- 4 files changed, 133 insertions(+), 101 deletions(-) diff --git a/hathor/event/model/event_data.py b/hathor/event/model/event_data.py index 343b445d2..f3003d0cd 100644 --- a/hathor/event/model/event_data.py +++ b/hathor/event/model/event_data.py @@ -20,16 +20,23 @@ from hathor.utils.pydantic import BaseModel -class TxInput(BaseModel): - tx_id: str - index: int - data: str +class DecodedTxOutput(BaseModel, extra=Extra.ignore): + type: str + address: str + timelock: Optional[int] -class TxOutput(BaseModel): +class TxOutput(BaseModel, extra=Extra.ignore): value: int - script: str token_data: int + script: str + decoded: Optional[DecodedTxOutput] + + +class TxInput(BaseModel): + tx_id: str + index: int + spent_output: TxOutput class SpentOutput(BaseModel): @@ -108,7 +115,23 @@ class TxData(BaseEventData, extra=Extra.ignore): @classmethod def from_event_arguments(cls, args: EventArguments) -> 'TxData': - tx_json = args.tx.to_json(include_metadata=True) + from hathor.transaction.resources.transaction import get_tx_extra_data + tx_extra_data_json = get_tx_extra_data(args.tx, detail_tokens=False) + tx_json = tx_extra_data_json['tx'] + meta_json = tx_extra_data_json['meta'] + tx_json['metadata'] = meta_json + tx_json['outputs'] = [ + output | dict(decoded=output['decoded'] or None) + for output in tx_json['outputs'] + ] + tx_json['inputs'] = [ + dict( + tx_id=input_['tx_id'], + index=input_['index'], + spent_output=input_ + ) + for input_ in tx_json['inputs'] + ] return cls(**tx_json) diff --git a/hathor/transaction/resources/transaction.py b/hathor/transaction/resources/transaction.py index 5763be4f8..803e21899 100644 --- a/hathor/transaction/resources/transaction.py +++ b/hathor/transaction/resources/transaction.py @@ -44,7 +44,7 @@ def update_serialized_tokens_array(tx: BaseTransaction, serialized: dict[str, An serialized['tokens'] = [h.hex() for h in tx.tokens] -def get_tx_extra_data(tx: BaseTransaction) -> dict[str, Any]: +def get_tx_extra_data(tx: BaseTransaction, *, detail_tokens: bool = True) -> dict[str, Any]: """ Get the data of a tx to be returned to the frontend Returns success, tx serializes, metadata and spent outputs """ @@ -116,18 +116,19 @@ def get_tx_extra_data(tx: BaseTransaction) -> dict[str, Any]: serialized['inputs'] = inputs - detailed_tokens = [] - for token_uid_hex in serialized['tokens']: - tokens_index = tx.storage.indexes.tokens - assert tokens_index is not None - token_info = tokens_index.get_token_info(bytes.fromhex(token_uid_hex)) - detailed_tokens.append({ - 'uid': token_uid_hex, - 'name': token_info.get_name(), - 'symbol': token_info.get_symbol(), - }) - - serialized['tokens'] = detailed_tokens + if detail_tokens: + detailed_tokens = [] + for token_uid_hex in serialized['tokens']: + tokens_index = tx.storage.indexes.tokens + assert tokens_index is not None + token_info = tokens_index.get_token_info(bytes.fromhex(token_uid_hex)) + detailed_tokens.append({ + 'uid': token_uid_hex, + 'name': token_info.get_name(), + 'symbol': token_info.get_symbol(), + }) + + serialized['tokens'] = detailed_tokens return { 'success': True, diff --git a/tests/event/test_event_reorg.py b/tests/event/test_event_reorg.py index c7c4b5560..ab058f18f 100644 --- a/tests/event/test_event_reorg.py +++ b/tests/event/test_event_reorg.py @@ -4,7 +4,7 @@ from hathor.event.model.event_type import EventType from hathor.event.storage import EventMemoryStorage from tests import unittest -from tests.utils import add_new_blocks, get_genesis_key +from tests.utils import BURN_ADDRESS, add_new_blocks, get_genesis_key settings = HathorSettings() @@ -37,7 +37,7 @@ def test_reorg_events(self): self.log.debug('make reorg block') block_to_replace = blocks[8] tb0 = self.manager.make_custom_block_template(block_to_replace.parents[0], block_to_replace.parents[1:]) - b0 = tb0.generate_mining_block(self.manager.rng, storage=self.manager.tx_storage) + b0 = tb0.generate_mining_block(self.manager.rng, storage=self.manager.tx_storage, address=BURN_ADDRESS) b0.weight = 10 b0.resolve() b0.verify() diff --git a/tests/event/test_event_simulation_scenarios.py b/tests/event/test_event_simulation_scenarios.py index 37ce4ccea..f7d4140d6 100644 --- a/tests/event/test_event_simulation_scenarios.py +++ b/tests/event/test_event_simulation_scenarios.py @@ -14,7 +14,16 @@ from hathor.cli.events_simulator.scenario import Scenario from hathor.event.model.base_event import BaseEvent -from hathor.event.model.event_data import EmptyData, ReorgData, SpentOutput, TxData, TxInput, TxMetadata, TxOutput +from hathor.event.model.event_data import ( + DecodedTxOutput, + EmptyData, + ReorgData, + SpentOutput, + TxData, + TxInput, + TxMetadata, + TxOutput, +) from hathor.event.model.event_type import EventType from hathor.event.websocket.request import StartStreamRequest from hathor.event.websocket.response import EventResponse @@ -43,7 +52,7 @@ def test_only_load(self) -> None: # LOAD_STATED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=4), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4), # noqa: E501 # LOAD_FINISHED @@ -60,19 +69,19 @@ def test_single_chain_one_block(self): expected = [ # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=8), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=8), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=8), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=8), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8) # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8) # noqa: E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' @@ -85,56 +94,55 @@ def test_single_chain_blocks_and_transactions(self): expected = [ # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 # One VERTEX_METADATA_CHANGED and one NEW_VERTEX_ACCEPTED for 10 new blocks - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', token_data=0)], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', token_data=0)], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', token_data=0)], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', token_data=0)], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', token_data=0)], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', token_data=0)], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', token_data=0)], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', token_data=0)], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', token_data=0)], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', token_data=0)], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', token_data=0)], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', token_data=0)], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=21, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', token_data=0)], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=22, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', token_data=0)], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=23, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', token_data=0)], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=24, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', token_data=0)], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=25, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', token_data=0)], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=26, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', token_data=0)], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=27, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', token_data=0)], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=28, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', token_data=0)], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a block, adding the new tx as spending their output # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=29, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=30, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[SpentOutput(index=0, tx_ids=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'])], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HF1E8Aibb17Rha6r1cM1oCp74DRmYqP61V', timelock=None))], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HF1E8Aibb17Rha6r1cM1oCp74DRmYqP61V', timelock=None))], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPeHcEFtRZvMBijqFwccicDMkN17hoNq21', timelock=None))], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPeHcEFtRZvMBijqFwccicDMkN17hoNq21', timelock=None))], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HRNWR1HpdAiDx7va9VkNUuqqSo2MGW5iE6', timelock=None))], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HRNWR1HpdAiDx7va9VkNUuqqSo2MGW5iE6', timelock=None))], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HU3chqobPRBt8pjYXt4WahKERjV8UMCWbd', timelock=None))], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HU3chqobPRBt8pjYXt4WahKERjV8UMCWbd', timelock=None))], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFrY3outhFVXGLEvaVKVFkd2nB1ihumXCr', timelock=None))], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFrY3outhFVXGLEvaVKVFkd2nB1ihumXCr', timelock=None))], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC4kH6pnYBofzTSFWRpA71Po7geNURh5p2', timelock=None))], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC4kH6pnYBofzTSFWRpA71Po7geNURh5p2', timelock=None))], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=21, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HQYUSF8ytNmm92GYMCS8XPYkt3JeKkBDyj', timelock=None))], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=22, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HQYUSF8ytNmm92GYMCS8XPYkt3JeKkBDyj', timelock=None))], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=23, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HTHNdEhmQeECj5brwUzHK4Sq3fFrFiEvaK', timelock=None))], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=24, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HTHNdEhmQeECj5brwUzHK4Sq3fFrFiEvaK', timelock=None))], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=25, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLUD2fi9udkg3ysPKdGvbWDyHFWdXBY1i1', timelock=None))], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=26, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLUD2fi9udkg3ysPKdGvbWDyHFWdXBY1i1', timelock=None))], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=27, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFJRMUG7GTjdqG5f6e5tqnrnquBMFCvvs2', timelock=None))], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=28, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFJRMUG7GTjdqG5f6e5tqnrnquBMFCvvs2', timelock=None))], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a block, adding the new tx as spending their output # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=29, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=30, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[SpentOutput(index=0, tx_ids=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'])], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new tx - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=31, timestamp=1578878970.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a tx, adding the new tx as spending their output and children # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, data='RjBEAiAYv9mzh3RMOpZvHEWgNIvBIdlkUGXK14v5fMf9kH8GkAIgcAld8/EAJuJ7YPnUy1LiUElgvhHnz5cH8zacyGj2B7YhA6cFdKG+mKglmA3FjLiWAKDijzhTD2dw5C6/2bE9YSp6')], outputs=[TxOutput(value=3400, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=2000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=31, timestamp=1578878970.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a tx, adding the new tx as spending their output and children # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879030.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new tx - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879030.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, data='RjBEAiAYv9mzh3RMOpZvHEWgNIvBIdlkUGXK14v5fMf9kH8GkAIgcAld8/EAJuJ7YPnUy1LiUElgvhHnz5cH8zacyGj2B7YhA6cFdKG+mKglmA3FjLiWAKDijzhTD2dw5C6/2bE9YSp6')], outputs=[TxOutput(value=3400, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=2000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each confirmed transaction # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, data='RzBFAiEA3jerjiviXpAqdUHUn+vbIYYzZW6KfP3/qf/nCTeUVecCICSQCLrkPrJR34ETfD/6r2GEGXknKfjDqZVT1I7dFX7jIQNMzeyxIMXLMD5B221u5nZ5Eucr4mmRYIyA9ZoaUmUkHw==')], outputs=[TxOutput(value=5400, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', token_data=0), TxOutput(value=1000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', token_data=0)], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=37, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, data='RjBEAiAYv9mzh3RMOpZvHEWgNIvBIdlkUGXK14v5fMf9kH8GkAIgcAld8/EAJuJ7YPnUy1LiUElgvhHnz5cH8zacyGj2B7YhA6cFdKG+mKglmA3FjLiWAKDijzhTD2dw5C6/2bE9YSp6')], outputs=[TxOutput(value=3400, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', token_data=0), TxOutput(value=2000, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=37, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=38, timestamp=1578879091.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', token_data=0)], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38) # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=38, timestamp=1578879091.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38) # noqa: E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' @@ -146,40 +154,40 @@ def test_reorg(self): responses = self._get_success_responses() expected = [ - # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa E501 + # # LOAD_STATED + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', token_data=0)], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager1 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878940.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878940.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 # Also one VERTEX_METADATA_CHANGED for the previous block, voiding it - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578879064.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578879064.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 # REORG_STARTED caused by a new block from manager2 (below) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578879064.25, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=1, previous_best_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', new_best_block='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', common_block='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792'), group_id=0), latest_event_id=20), # noqa E501 - # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa E501 - # Also one VERTEX_METADATA_CHANGED for the previous block, un-voiding it as it's now part of the best blockchain # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', token_data=0)], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', token_data=0)], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578879064.25, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=1, previous_best_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', new_best_block='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', common_block='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792'), group_id=0), latest_event_id=20), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 + # Also one VERTEX_METADATA_CHANGED for the previous block, un-voiding it as it's now part of the best blockchain # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 # REORG_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578879064.25, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), latest_event_id=20), # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578879064.25, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), latest_event_id=20), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578879064.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', token_data=0)], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=20) # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578879064.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=20) # noqa: E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' From db50c74ea7293ebad4fb2f5961946b814ada472b Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Thu, 24 Aug 2023 16:42:07 -0300 Subject: [PATCH 03/26] tests: decrease tests duration --- hathor/simulator/miner/geometric_miner.py | 2 +- .../test_mining_simulation.py | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/hathor/simulator/miner/geometric_miner.py b/hathor/simulator/miner/geometric_miner.py index 53a0b8c0d..0eb9aa1f8 100644 --- a/hathor/simulator/miner/geometric_miner.py +++ b/hathor/simulator/miner/geometric_miner.py @@ -124,7 +124,7 @@ def pause_after_exactly(self, *, n_blocks: int) -> None: will unpause the miner and pause again according to the new argument. Use this instead of the `StopAfterNMinedBlocks` trigger if you need "exactly N blocks" behavior, instead of - "at least N blocks". + "at least N blocks". Use both to prevent the simulator from running more steps than necessary. """ self._blocks_before_pause = n_blocks diff --git a/tests/feature_activation/test_mining_simulation.py b/tests/feature_activation/test_mining_simulation.py index d8e785a49..d414bf789 100644 --- a/tests/feature_activation/test_mining_simulation.py +++ b/tests/feature_activation/test_mining_simulation.py @@ -26,6 +26,7 @@ from hathor.feature_activation.settings import Settings as FeatureSettings from hathor.mining.ws import MiningWebsocketFactory, MiningWebsocketProtocol from hathor.p2p.resources import MiningResource +from hathor.simulator.trigger import StopAfterNMinedBlocks from hathor.transaction.resources import GetBlockTemplateResource from hathor.transaction.util import unpack, unpack_len from hathor.util import json_loadb @@ -88,55 +89,55 @@ def test_signal_bits_in_mining(self) -> None: expected_signal_bits = 0b0000 assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] miner.pause_after_exactly(n_blocks=6) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=6)) assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 6 # At height=8, NOP_FEATURE_1 is signaling, so it's enabled by the default support. expected_signal_bits = 0b0001 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] miner.pause_after_exactly(n_blocks=3) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=3)) assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 3 # At height=12, NOP_FEATURE_2 is signaling, enabled by the user. NOP_FEATURE_1 also continues signaling. expected_signal_bits = 0b0101 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] miner.pause_after_exactly(n_blocks=7) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=7)) assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 7 # At height=20, NOP_FEATURE_1 stops signaling, and NOP_FEATURE_2 continues. expected_signal_bits = 0b0100 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] miner.pause_after_exactly(n_blocks=3) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=3)) assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 3 # At height=24, all features have left their signaling period and therefore none are signaled. expected_signal_bits = 0b0000 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600) + self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] From a847f51b2427d64d7db02fac6db9639ba0be6d60 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 25 Aug 2023 00:21:17 -0300 Subject: [PATCH 04/26] tests: decrease tests duration --- hathor/simulator/miner/geometric_miner.py | 2 +- .../test_mining_simulation.py | 47 ++++++++++--------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/hathor/simulator/miner/geometric_miner.py b/hathor/simulator/miner/geometric_miner.py index 0eb9aa1f8..53a0b8c0d 100644 --- a/hathor/simulator/miner/geometric_miner.py +++ b/hathor/simulator/miner/geometric_miner.py @@ -124,7 +124,7 @@ def pause_after_exactly(self, *, n_blocks: int) -> None: will unpause the miner and pause again according to the new argument. Use this instead of the `StopAfterNMinedBlocks` trigger if you need "exactly N blocks" behavior, instead of - "at least N blocks". Use both to prevent the simulator from running more steps than necessary. + "at least N blocks". """ self._blocks_before_pause = n_blocks diff --git a/tests/feature_activation/test_mining_simulation.py b/tests/feature_activation/test_mining_simulation.py index d414bf789..cb306a693 100644 --- a/tests/feature_activation/test_mining_simulation.py +++ b/tests/feature_activation/test_mining_simulation.py @@ -26,7 +26,6 @@ from hathor.feature_activation.settings import Settings as FeatureSettings from hathor.mining.ws import MiningWebsocketFactory, MiningWebsocketProtocol from hathor.p2p.resources import MiningResource -from hathor.simulator.trigger import StopAfterNMinedBlocks from hathor.transaction.resources import GetBlockTemplateResource from hathor.transaction.util import unpack, unpack_len from hathor.util import json_loadb @@ -67,7 +66,7 @@ def test_signal_bits_in_mining(self) -> None: manager = self.simulator.create_peer(builder) manager.allow_mining_without_peers() - miner = self.simulator.create_miner(manager, hashpower=1e6) + miner = self.simulator.create_miner(manager, hashpower=1e12) miner.start() # There are 3 resources available for miners, and all of them should contain the correct signal_bits @@ -87,60 +86,60 @@ def test_signal_bits_in_mining(self) -> None: # At the beginning, all features are outside their signaling period, so none are signaled. expected_signal_bits = 0b0000 - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) + self.simulator.run(60) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits miner.pause_after_exactly(n_blocks=6) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=6)) - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 6 + self.simulator.run(360) + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits # At height=8, NOP_FEATURE_1 is signaling, so it's enabled by the default support. expected_signal_bits = 0b0001 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) + self.simulator.run(60) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits miner.pause_after_exactly(n_blocks=3) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=3)) - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 3 + self.simulator.run(180) + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits # At height=12, NOP_FEATURE_2 is signaling, enabled by the user. NOP_FEATURE_1 also continues signaling. expected_signal_bits = 0b0101 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) + self.simulator.run(60) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits miner.pause_after_exactly(n_blocks=7) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=7)) - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 7 + self.simulator.run(360) + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits # At height=20, NOP_FEATURE_1 stops signaling, and NOP_FEATURE_2 continues. expected_signal_bits = 0b0100 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) + self.simulator.run(60) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits miner.pause_after_exactly(n_blocks=3) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=3)) - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] * 3 + self.simulator.run(180) + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits # At height=24, all features have left their signaling period and therefore none are signaled. expected_signal_bits = 0b0000 miner.pause_after_exactly(n_blocks=1) - self.simulator.run(3600, trigger=StopAfterNMinedBlocks(miner, quantity=1)) + self.simulator.run(60) assert self._get_signal_bits_from_get_block_template(get_block_template_client) == expected_signal_bits assert self._get_signal_bits_from_mining(mining_client) == expected_signal_bits - assert self._get_ws_signal_bits(ws_transport) == [expected_signal_bits] + assert self._get_last_ws_signal_bits(ws_transport) == expected_signal_bits def _get_signal_bits_from_get_block_template(self, web_client: StubSite) -> int: result = self._get_result(web_client) @@ -156,9 +155,11 @@ def _get_result(web_client: StubSite) -> dict[str, Any]: response = web_client.get('') return response.result.json_value() - def _get_ws_signal_bits(self, transport: StringTransport) -> list[int]: + def _get_last_ws_signal_bits(self, transport: StringTransport) -> int: messages = self._get_transport_messages(transport) - signal_bits = [message['params'][0]['signal_bits'] for message in messages] + assert len(messages) > 0 + last_message = messages[-1] + signal_bits = last_message['params'][0]['signal_bits'] return signal_bits From 2ebb62fba02e2b7d381c0c2e1c3e24a52822de4a Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Tue, 12 Sep 2023 01:16:22 -0300 Subject: [PATCH 05/26] feat(reliable-integration): implement stream ID (#766) --- .../cli/events_simulator/events_simulator.py | 2 +- hathor/event/event_manager.py | 10 +- hathor/event/storage/event_storage.py | 14 +- hathor/event/storage/memory_storage.py | 8 + hathor/event/storage/rocksdb_storage.py | 16 ++ hathor/event/websocket/factory.py | 16 +- hathor/event/websocket/response.py | 2 + .../event/test_event_simulation_scenarios.py | 152 +++++++++--------- tests/event/websocket/test_factory.py | 17 +- tests/event/websocket/test_protocol.py | 6 +- 10 files changed, 151 insertions(+), 92 deletions(-) diff --git a/hathor/cli/events_simulator/events_simulator.py b/hathor/cli/events_simulator/events_simulator.py index 5491d3c28..a915585de 100644 --- a/hathor/cli/events_simulator/events_simulator.py +++ b/hathor/cli/events_simulator/events_simulator.py @@ -80,7 +80,7 @@ def execute(args: Namespace) -> None: log.info('Started simulating events', scenario=args.scenario, seed=simulator.seed) - forwarding_ws_factory.start() + forwarding_ws_factory.start(stream_id='simulator') scenario.simulate(simulator, manager) reactor.listenTCP(args.port, site) reactor.run() diff --git a/hathor/event/event_manager.py b/hathor/event/event_manager.py index d8c0a10a4..4ac536e6c 100644 --- a/hathor/event/event_manager.py +++ b/hathor/event/event_manager.py @@ -13,6 +13,7 @@ # limitations under the License. from typing import Callable, Iterator, Optional +from uuid import uuid4 from structlog import get_logger @@ -23,7 +24,7 @@ from hathor.event.websocket import EventWebsocketFactory from hathor.pubsub import EventArguments, HathorEvents, PubSubManager from hathor.transaction import BaseTransaction -from hathor.util import Reactor, progress +from hathor.util import Reactor, not_none, progress from hathor.utils.iter import batch_iterator logger = get_logger() @@ -55,6 +56,7 @@ class EventManager: _peer_id: str _is_running: bool = False _previous_node_state: Optional[NodeState] = None + _stream_id: Optional[str] = None _last_event: Optional[BaseEvent] = None _last_existing_group_id: Optional[int] = None @@ -86,16 +88,20 @@ def start(self, peer_id: str) -> None: if self._should_reload_events(): self._event_storage.reset_events() + self._stream_id = str(uuid4()) + self._event_storage.save_stream_id(self._stream_id) else: self._last_event = self._event_storage.get_last_event() self._last_existing_group_id = self._event_storage.get_last_group_id() + self._stream_id = not_none(self._event_storage.get_stream_id()) self._assert_closed_event_group() self._subscribe_events() self._peer_id = peer_id - self._event_ws_factory.start() + self._event_ws_factory.start(stream_id=not_none(self._stream_id)) self._is_running = True + self.log.info('Starting Event Manager', stream_id=self._stream_id) def stop(self) -> None: """Stops the EventManager.""" diff --git a/hathor/event/storage/event_storage.py b/hathor/event/storage/event_storage.py index 00677c297..51f33f14f 100644 --- a/hathor/event/storage/event_storage.py +++ b/hathor/event/storage/event_storage.py @@ -53,7 +53,7 @@ def iter_from_event(self, key: int) -> Iterator[BaseEvent]: @abstractmethod def reset_events(self) -> None: """ - Reset event-related data: events, last_event, and last_group_id. + Reset event-related data: events, last_event, last_group_id, and stream_id. This should be used to clear old events from the database when reloading events. """ raise NotImplementedError @@ -61,7 +61,7 @@ def reset_events(self) -> None: @abstractmethod def reset_all(self) -> None: """ - Reset all data and metadata: events, last_event, last_group_id, node_state, and event_queue_enabled. + Reset all data and metadata: events, last_event, last_group_id, stream_id, node_state, and event_queue_enabled. This should be used for a full wipe out of the event storage. """ raise NotImplementedError @@ -85,3 +85,13 @@ def save_event_queue_state(self, enabled: bool) -> None: def get_event_queue_state(self) -> bool: """Get whether the event queue feature is enabled from the storage""" raise NotImplementedError + + @abstractmethod + def save_stream_id(self, stream_id: str) -> None: + """Save the Stream ID.""" + raise NotImplementedError + + @abstractmethod + def get_stream_id(self) -> Optional[str]: + """Get the Stream ID.""" + raise NotImplementedError diff --git a/hathor/event/storage/memory_storage.py b/hathor/event/storage/memory_storage.py index d7ec9cb7c..6de5c6df5 100644 --- a/hathor/event/storage/memory_storage.py +++ b/hathor/event/storage/memory_storage.py @@ -24,6 +24,7 @@ def __init__(self) -> None: self._events: list[BaseEvent] = [] self._last_event: Optional[BaseEvent] = None self._last_group_id: Optional[int] = None + self._stream_id: Optional[str] = None self._node_state: Optional[NodeState] = None self._event_queue_enabled: bool = False @@ -66,6 +67,7 @@ def reset_events(self) -> None: self._events = [] self._last_event = None self._last_group_id = None + self._stream_id = None def reset_all(self) -> None: self.reset_events() @@ -83,3 +85,9 @@ def save_event_queue_state(self, enabled: bool) -> None: def get_event_queue_state(self) -> bool: return self._event_queue_enabled + + def save_stream_id(self, stream_id: str) -> None: + self._stream_id = stream_id + + def get_stream_id(self) -> Optional[str]: + return self._stream_id diff --git a/hathor/event/storage/rocksdb_storage.py b/hathor/event/storage/rocksdb_storage.py index 1c675e2f9..b1709473c 100644 --- a/hathor/event/storage/rocksdb_storage.py +++ b/hathor/event/storage/rocksdb_storage.py @@ -30,6 +30,7 @@ _KEY_LAST_GROUP_ID = b'last-group-id' _KEY_NODE_STATE = b'node-state' _KEY_EVENT_QUEUE_ENABLED = b'event-queue-enabled' +_KEY_STREAM_ID = b'stream-id' class EventRocksDBStorage(EventStorage): @@ -112,6 +113,7 @@ def reset_events(self) -> None: self._last_group_id = None self._db.delete((self._cf_meta, _KEY_LAST_GROUP_ID)) + self._db.delete((self._cf_meta, _KEY_STREAM_ID)) self._db.drop_column_family(self._cf_event) self._cf_event = self._rocksdb_storage.get_or_create_column_family(_CF_NAME_EVENT) @@ -147,3 +149,17 @@ def get_event_queue_state(self) -> bool: return False return bool.from_bytes(enabled_bytes, byteorder='big') + + def save_stream_id(self, stream_id: str) -> None: + self._db.put( + (self._cf_meta, _KEY_STREAM_ID), + stream_id.encode('utf8') + ) + + def get_stream_id(self) -> Optional[str]: + stream_id_bytes: bytes = self._db.get((self._cf_meta, _KEY_STREAM_ID)) + + if stream_id_bytes is None: + return None + + return stream_id_bytes.decode('utf8') diff --git a/hathor/event/websocket/factory.py b/hathor/event/websocket/factory.py index f13a425f6..9d024bdad 100644 --- a/hathor/event/websocket/factory.py +++ b/hathor/event/websocket/factory.py @@ -21,7 +21,7 @@ from hathor.event.storage import EventStorage from hathor.event.websocket.protocol import EventWebsocketProtocol from hathor.event.websocket.response import EventResponse, InvalidRequestType -from hathor.util import Reactor +from hathor.util import Reactor, not_none logger = get_logger() @@ -37,6 +37,9 @@ class EventWebsocketFactory(WebSocketServerFactory): # The last event id broadcast by this factory. _latest_event_id: Optional[int] = None + # The unique stream ID + _stream_id: Optional[str] = None + def __init__(self, reactor: Reactor, event_storage: EventStorage): super().__init__() self.log = logger.new() @@ -49,13 +52,14 @@ def __init__(self, reactor: Reactor, event_storage: EventStorage): if latest_event is not None: self._latest_event_id = latest_event.id - def start(self): + def start(self, *, stream_id: str) -> None: """Start the WebSocket server. Required to be able to send events.""" assert self._is_running is False, 'Cannot start, EventWebsocketFactory is already running' self._is_running = True + self._stream_id = stream_id - def stop(self): + def stop(self) -> None: """Stop the WebSocket server. No events can be sent.""" assert self._is_running is True, 'Cannot stop, EventWebsocketFactory is not running' @@ -108,6 +112,10 @@ def _send_event_to_connection(self, connection: EventWebsocketProtocol, event: B assert self._latest_event_id is not None, '_latest_event_id must be set.' - response = EventResponse(event=event, latest_event_id=self._latest_event_id) + response = EventResponse( + event=event, + latest_event_id=self._latest_event_id, + stream_id=not_none(self._stream_id) + ) connection.send_event_response(response) diff --git a/hathor/event/websocket/response.py b/hathor/event/websocket/response.py index 618de54a6..78bbe4c65 100644 --- a/hathor/event/websocket/response.py +++ b/hathor/event/websocket/response.py @@ -31,11 +31,13 @@ class EventResponse(Response): type: The type of the response. event: The event. latest_event_id: The ID of the latest event known by the server. + stream_id: The ID of the current stream. """ type: str = Field(default='EVENT', const=True) event: BaseEvent latest_event_id: NonNegativeInt + stream_id: str class InvalidRequestType(Enum): diff --git a/tests/event/test_event_simulation_scenarios.py b/tests/event/test_event_simulation_scenarios.py index f7d4140d6..e87b91f0e 100644 --- a/tests/event/test_event_simulation_scenarios.py +++ b/tests/event/test_event_simulation_scenarios.py @@ -43,6 +43,7 @@ class BaseEventSimulationScenariosTest(BaseEventSimulationTester): seed_config = 6946502462188444706 def test_only_load(self) -> None: + stream_id = self.manager._event_manager._stream_id Scenario.ONLY_LOAD.simulate(self.simulator, self.manager) self._start_stream() @@ -50,18 +51,19 @@ def test_only_load(self) -> None: expected = [ # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=4), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=4, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=4, stream_id=stream_id), # noqa: E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=4) # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=4, stream_id=stream_id) # noqa: E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' def test_single_chain_one_block(self): + stream_id = self.manager._event_manager._stream_id Scenario.SINGLE_CHAIN_ONE_BLOCK.simulate(self.simulator, self.manager) self._start_stream() @@ -69,24 +71,25 @@ def test_single_chain_one_block(self): expected = [ # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=8), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=8), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8) # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id) # noqa: E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' def test_single_chain_blocks_and_transactions(self): + stream_id = self.manager._event_manager._stream_id Scenario.SINGLE_CHAIN_BLOCKS_AND_TRANSACTIONS.simulate(self.simulator, self.manager) self._start_stream() @@ -94,60 +97,61 @@ def test_single_chain_blocks_and_transactions(self): expected = [ # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED and one NEW_VERTEX_ACCEPTED for 10 new blocks - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HF1E8Aibb17Rha6r1cM1oCp74DRmYqP61V', timelock=None))], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HF1E8Aibb17Rha6r1cM1oCp74DRmYqP61V', timelock=None))], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPeHcEFtRZvMBijqFwccicDMkN17hoNq21', timelock=None))], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPeHcEFtRZvMBijqFwccicDMkN17hoNq21', timelock=None))], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HRNWR1HpdAiDx7va9VkNUuqqSo2MGW5iE6', timelock=None))], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HRNWR1HpdAiDx7va9VkNUuqqSo2MGW5iE6', timelock=None))], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HU3chqobPRBt8pjYXt4WahKERjV8UMCWbd', timelock=None))], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HU3chqobPRBt8pjYXt4WahKERjV8UMCWbd', timelock=None))], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFrY3outhFVXGLEvaVKVFkd2nB1ihumXCr', timelock=None))], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFrY3outhFVXGLEvaVKVFkd2nB1ihumXCr', timelock=None))], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC4kH6pnYBofzTSFWRpA71Po7geNURh5p2', timelock=None))], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC4kH6pnYBofzTSFWRpA71Po7geNURh5p2', timelock=None))], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=21, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HQYUSF8ytNmm92GYMCS8XPYkt3JeKkBDyj', timelock=None))], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=22, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HQYUSF8ytNmm92GYMCS8XPYkt3JeKkBDyj', timelock=None))], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=23, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HTHNdEhmQeECj5brwUzHK4Sq3fFrFiEvaK', timelock=None))], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=24, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HTHNdEhmQeECj5brwUzHK4Sq3fFrFiEvaK', timelock=None))], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=25, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLUD2fi9udkg3ysPKdGvbWDyHFWdXBY1i1', timelock=None))], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=26, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLUD2fi9udkg3ysPKdGvbWDyHFWdXBY1i1', timelock=None))], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=27, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFJRMUG7GTjdqG5f6e5tqnrnquBMFCvvs2', timelock=None))], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=28, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFJRMUG7GTjdqG5f6e5tqnrnquBMFCvvs2', timelock=None))], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HF1E8Aibb17Rha6r1cM1oCp74DRmYqP61V', timelock=None))], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', nonce=0, timestamp=1578878911, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUXRFxfhIYOXURHjiAlx9XPuMh7E2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HF1E8Aibb17Rha6r1cM1oCp74DRmYqP61V', timelock=None))], parents=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8'], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPeHcEFtRZvMBijqFwccicDMkN17hoNq21', timelock=None))], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', nonce=0, timestamp=1578878912, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUu9S/kjy3HbglEu3bA4JargdORiiIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPeHcEFtRZvMBijqFwccicDMkN17hoNq21', timelock=None))], parents=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393'], twins=[], accumulated_weight=2.0, score=4.584962500721156, first_block=None, height=3, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HRNWR1HpdAiDx7va9VkNUuqqSo2MGW5iE6', timelock=None))], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', nonce=0, timestamp=1578878913, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUzskI6jayLvTobJDhpVZiuMu7zt+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HRNWR1HpdAiDx7va9VkNUuqqSo2MGW5iE6', timelock=None))], parents=['32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49'], twins=[], accumulated_weight=2.0, score=4.807354922057604, first_block=None, height=4, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HU3chqobPRBt8pjYXt4WahKERjV8UMCWbd', timelock=None))], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', nonce=0, timestamp=1578878914, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU7B7Cf/pnj2DglfhnqyiRzxNg+K2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HU3chqobPRBt8pjYXt4WahKERjV8UMCWbd', timelock=None))], parents=['896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3'], twins=[], accumulated_weight=2.0, score=5.0, first_block=None, height=5, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFrY3outhFVXGLEvaVKVFkd2nB1ihumXCr', timelock=None))], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', nonce=0, timestamp=1578878915, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUZmTJ0of2Ce9iuycIVpFCVU08WmKIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFrY3outhFVXGLEvaVKVFkd2nB1ihumXCr', timelock=None))], parents=['0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e'], twins=[], accumulated_weight=2.0, score=5.169925001442312, first_block=None, height=6, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC4kH6pnYBofzTSFWRpA71Po7geNURh5p2', timelock=None))], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', nonce=0, timestamp=1578878916, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPNN8M/qangqd2wYSzu0u+3OmwDmIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC4kH6pnYBofzTSFWRpA71Po7geNURh5p2', timelock=None))], parents=['97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d'], twins=[], accumulated_weight=2.0, score=5.321928094887363, first_block=None, height=7, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=21, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HQYUSF8ytNmm92GYMCS8XPYkt3JeKkBDyj', timelock=None))], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=22, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', nonce=0, timestamp=1578878917, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUxbNqvpWbgNtk9km/VuYhzHHMp76IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HQYUSF8ytNmm92GYMCS8XPYkt3JeKkBDyj', timelock=None))], parents=['6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6'], twins=[], accumulated_weight=2.0, score=5.459431618637297, first_block=None, height=8, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=23, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HTHNdEhmQeECj5brwUzHK4Sq3fFrFiEvaK', timelock=None))], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=24, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', nonce=0, timestamp=1578878918, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkU48C0XcFpiaWq2gwTICyEVdvJXcCIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HTHNdEhmQeECj5brwUzHK4Sq3fFrFiEvaK', timelock=None))], parents=['fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7'], twins=[], accumulated_weight=2.0, score=5.584962500721156, first_block=None, height=9, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=25, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLUD2fi9udkg3ysPKdGvbWDyHFWdXBY1i1', timelock=None))], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=26, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', nonce=0, timestamp=1578878919, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUmQRjqRyxq26raJZnhnpRJsrS9n2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLUD2fi9udkg3ysPKdGvbWDyHFWdXBY1i1', timelock=None))], parents=['eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=5.700439718141092, first_block=None, height=10, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=27, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFJRMUG7GTjdqG5f6e5tqnrnquBMFCvvs2', timelock=None))], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=28, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', nonce=0, timestamp=1578878920, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUYFHjcujZZHs0JWZkriEbn5jTv/aIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HFJRMUG7GTjdqG5f6e5tqnrnquBMFCvvs2', timelock=None))], parents=['1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=5.807354922057604, first_block=None, height=11, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a block, adding the new tx as spending their output # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=29, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=30, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[SpentOutput(index=0, tx_ids=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'])], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=29, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=30, timestamp=1578878970.5, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[SpentOutput(index=0, tx_ids=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'])], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new tx - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=31, timestamp=1578878970.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=31, timestamp=1578878970.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a tx, adding the new tx as spending their output and children # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879030.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879030.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new tx - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=37, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=37, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=38, timestamp=1578879091.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38) # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=38, timestamp=1578879091.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id) # noqa: E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' def test_reorg(self): + stream_id = self.manager._event_manager._stream_id Scenario.REORG.simulate(self.simulator, self.manager) self._start_stream() @@ -155,39 +159,39 @@ def test_reorg(self): expected = [ # # LOAD_STATED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=2, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=3, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # LOAD_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager1 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878940.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878940.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 # Also one VERTEX_METADATA_CHANGED for the previous block, voiding it - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578879064.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578879064.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # REORG_STARTED caused by a new block from manager2 (below) - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578879064.25, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=1, previous_best_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', new_best_block='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', common_block='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792'), group_id=0), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578879064.25, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=1, previous_best_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', new_best_block='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', common_block='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792'), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 # Also one VERTEX_METADATA_CHANGED for the previous block, un-voiding it as it's now part of the best blockchain # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 # REORG_FINISHED - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578879064.25, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), latest_event_id=20), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578879064.25, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578879064.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=20) # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=20, timestamp=1578879064.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id) # noqa: E501 ] assert responses == expected, f'expected: {expected}\n\nactual: {responses}' diff --git a/tests/event/websocket/test_factory.py b/tests/event/websocket/test_factory.py index c6e1b6cda..8bdb935fb 100644 --- a/tests/event/websocket/test_factory.py +++ b/tests/event/websocket/test_factory.py @@ -29,7 +29,7 @@ def test_started_register(): connection = Mock(spec_set=EventWebsocketProtocol) connection.send_invalid_request_response = Mock() - factory.start() + factory.start(stream_id='stream_id') factory.register(connection) connection.send_invalid_request_response.assert_not_called() @@ -50,7 +50,7 @@ def test_stopped_register(): connection = Mock(spec_set=EventWebsocketProtocol) connection.send_invalid_request_response = Mock() - factory.start() + factory.start(stream_id='stream_id') factory.stop() factory.register(connection) @@ -59,6 +59,7 @@ def test_stopped_register(): @pytest.mark.parametrize('can_receive_event', [False, True]) def test_broadcast_event(can_receive_event: bool) -> None: + stream_id = 'stream_id' n_starting_events = 10 factory = _get_factory(n_starting_events) event = EventMocker.create_event(n_starting_events - 1) @@ -66,18 +67,19 @@ def test_broadcast_event(can_receive_event: bool) -> None: connection.can_receive_event = Mock(return_value=can_receive_event) connection.send_event_response = Mock() - factory.start() + factory.start(stream_id=stream_id) factory.register(connection) factory.broadcast_event(event) if not can_receive_event: return connection.send_event_response.assert_not_called() - response = EventResponse(event=event, latest_event_id=n_starting_events - 1) + response = EventResponse(event=event, latest_event_id=n_starting_events - 1, stream_id=stream_id) connection.send_event_response.assert_called_once_with(response) def test_broadcast_multiple_events_multiple_connections(): + stream_id = 'stream_id' factory = _get_factory(10) connection1 = Mock(spec_set=EventWebsocketProtocol) connection1.can_receive_event = Mock(return_value=True) @@ -86,7 +88,7 @@ def test_broadcast_multiple_events_multiple_connections(): connection2.can_receive_event = Mock(return_value=True) connection2.send_event_response = Mock() - factory.start() + factory.start(stream_id=stream_id) factory.register(connection1) factory.register(connection2) @@ -108,6 +110,7 @@ def test_broadcast_multiple_events_multiple_connections(): ] ) def test_send_next_event_to_connection(next_expected_event_id: int, can_receive_event: bool) -> None: + stream_id = 'stream_id' n_starting_events = 10 clock = MemoryReactorHeapClock() factory = _get_factory(n_starting_events, clock) @@ -118,7 +121,7 @@ def test_send_next_event_to_connection(next_expected_event_id: int, can_receive_ side_effect=lambda: next_expected_event_id + connection.send_event_response.call_count ) - factory.start() + factory.start(stream_id=stream_id) factory.register(connection) factory.send_next_event_to_connection(connection) @@ -130,7 +133,7 @@ def test_send_next_event_to_connection(next_expected_event_id: int, can_receive_ calls = [] for _id in range(next_expected_event_id, n_starting_events): event = EventMocker.create_event(_id) - response = EventResponse(event=event, latest_event_id=n_starting_events - 1) + response = EventResponse(event=event, latest_event_id=n_starting_events - 1, stream_id=stream_id) calls.append(call(response)) assert connection.send_event_response.call_count == n_starting_events - next_expected_event_id diff --git a/tests/event/websocket/test_protocol.py b/tests/event/websocket/test_protocol.py index 0ebfeee1e..b7fa83544 100644 --- a/tests/event/websocket/test_protocol.py +++ b/tests/event/websocket/test_protocol.py @@ -90,7 +90,8 @@ def test_send_event_response(): type=EventType.VERTEX_METADATA_CHANGED, data=EventMocker.tx_data ), - latest_event_id=10 + latest_event_id=10, + stream_id='stream_id' ) protocol.send_event_response(response) @@ -101,7 +102,8 @@ def test_send_event_response(): b'"token_name":null,"token_symbol":null,"metadata":{"hash":"abc","spent_outputs":[],' \ b'"conflict_with":[],"voided_by":[],"received_by":[],"children":[],"twins":[],' \ b'"accumulated_weight":10.0,"score":20.0,"first_block":null,"height":100,' \ - b'"validation":"validation"},"aux_pow":null},"group_id":null},"latest_event_id":10}' + b'"validation":"validation"},"aux_pow":null},"group_id":null},"latest_event_id":10,' \ + b'"stream_id":"stream_id"}' protocol.sendMessage.assert_called_once_with(expected_payload) From dbeaa9ecf44dc738ad0c98ed819c1640bcf588ef Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Tue, 12 Sep 2023 17:39:26 -0300 Subject: [PATCH 06/26] refactor: move get settings [part 1] (#768) --- hathor/conf/get_settings.py | 4 +++ hathor/p2p/sync_v1/agent.py | 8 ++--- hathor/p2p/sync_v1/downloader.py | 10 +++--- hathor/p2p/sync_v2/agent.py | 8 ++--- hathor/p2p/utils.py | 5 ++- hathor/prometheus.py | 7 ++--- hathor/simulator/fake_connection.py | 3 -- hathor/simulator/miner/geometric_miner.py | 9 +++--- hathor/simulator/simulator.py | 4 +-- hathor/simulator/tx_generator.py | 6 ++-- hathor/stratum/stratum.py | 13 ++++---- hathor/transaction/__init__.py | 4 --- hathor/transaction/base_transaction.py | 22 ++++++------- hathor/transaction/block.py | 17 +++++----- hathor/transaction/token_creation_tx.py | 11 +++---- hathor/transaction/transaction.py | 30 +++++++++--------- tests/tx/test_tx.py | 38 ++++++++++------------- tests/unittest.py | 2 ++ 18 files changed, 92 insertions(+), 109 deletions(-) diff --git a/hathor/conf/get_settings.py b/hathor/conf/get_settings.py index 2cf8b46d7..c330ca795 100644 --- a/hathor/conf/get_settings.py +++ b/hathor/conf/get_settings.py @@ -33,6 +33,10 @@ class _SettingsMetadata(NamedTuple): _settings_singleton: Optional[_SettingsMetadata] = None +def get_settings() -> Settings: + return HathorSettings() + + def HathorSettings() -> Settings: """ Returns the configuration named tuple. diff --git a/hathor/p2p/sync_v1/agent.py b/hathor/p2p/sync_v1/agent.py index c2f90e0d5..ce3aea322 100644 --- a/hathor/p2p/sync_v1/agent.py +++ b/hathor/p2p/sync_v1/agent.py @@ -24,7 +24,7 @@ from twisted.internet.interfaces import IConsumer, IDelayedCall, IPushProducer from zope.interface import implementer -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.p2p.messages import GetNextPayload, GetTipsPayload, NextPayload, ProtocolMessages, TipsPayload from hathor.p2p.sync_agent import SyncAgent from hathor.p2p.sync_v1.downloader import Downloader @@ -34,7 +34,6 @@ from hathor.util import Reactor, json_dumps, json_loads from hathor.utils.zope import asserted_cast -settings = HathorSettings() logger = get_logger() if TYPE_CHECKING: @@ -191,6 +190,7 @@ def __init__(self, protocol: 'HathorProtocol', downloader: Downloader, reactor: :param reactor: Reactor to schedule later calls. (default=twisted.internet.reactor) :type reactor: Reactor """ + self._settings = get_settings() self.protocol = protocol self.manager = protocol.node self.downloader = downloader @@ -228,7 +228,7 @@ def __init__(self, protocol: 'HathorProtocol', downloader: Downloader, reactor: # Maximum difference between our latest timestamp and synced timestamp to consider # that the peer is synced (in seconds). - self.sync_threshold: int = settings.P2P_SYNC_THRESHOLD + self.sync_threshold: int = self._settings.P2P_SYNC_THRESHOLD # Indicate whether the sync manager has been started. self._started: bool = False @@ -624,7 +624,7 @@ def send_tips(self, timestamp: Optional[int] = None, include_hashes: bool = Fals """Try to send a TIPS message. If rate limit has been reached, it schedules to send it later.""" if not self.global_rate_limiter.add_hit(self.GlobalRateLimiter.SEND_TIPS): self.log.debug('send_tips throttled') - if len(self._send_tips_call_later) >= settings.MAX_GET_TIPS_DELAYED_CALLS: + if len(self._send_tips_call_later) >= self._settings.MAX_GET_TIPS_DELAYED_CALLS: self.protocol.send_error_and_close_connection( 'Too many GET_TIPS message' ) diff --git a/hathor/p2p/sync_v1/downloader.py b/hathor/p2p/sync_v1/downloader.py index ee068baca..c28863abb 100644 --- a/hathor/p2p/sync_v1/downloader.py +++ b/hathor/p2p/sync_v1/downloader.py @@ -20,11 +20,9 @@ from twisted.internet import defer from twisted.internet.defer import Deferred -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.transaction.storage.exceptions import TransactionDoesNotExist -settings = HathorSettings() - if TYPE_CHECKING: from hathor.manager import HathorManager from hathor.p2p.sync_v1.agent import NodeSyncTimestamp @@ -53,6 +51,7 @@ class TxDetails: requested_index: int def __init__(self, tx_id: bytes, deferred: Deferred, connections: list['NodeSyncTimestamp']): + self._settings = get_settings() self.log = logger.new() self.tx_id = tx_id self.deferred = deferred @@ -109,7 +108,7 @@ def get_connection(self) -> Optional['NodeSyncTimestamp']: self.retry_count += 1 # only try next peer if we reach max retries on the current one - if self.retry_count >= settings.GET_DATA_RETRIES: + if self.retry_count >= self._settings.GET_DATA_RETRIES: self.requested_index += 1 self.retry_count = 0 @@ -146,6 +145,7 @@ class Downloader: window_size: int def __init__(self, manager: 'HathorManager', window_size: int = 100): + self._settings = get_settings() self.log = logger.new() self.manager = manager @@ -227,7 +227,7 @@ def add_get_downloading_deferred(self, tx_id: bytes, details: TxDetails, connect # Adding timeout to callback fn_timeout = partial(self.on_deferred_timeout, tx_id=tx_id) details.downloading_deferred.addTimeout( - settings.GET_DATA_TIMEOUT, + self._settings.GET_DATA_TIMEOUT, connection.reactor, onTimeoutCancel=fn_timeout ) diff --git a/hathor/p2p/sync_v2/agent.py b/hathor/p2p/sync_v2/agent.py index 3fa948823..3ee2baa1f 100644 --- a/hathor/p2p/sync_v2/agent.py +++ b/hathor/p2p/sync_v2/agent.py @@ -24,7 +24,7 @@ from twisted.internet.defer import Deferred, inlineCallbacks from twisted.internet.task import LoopingCall -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.p2p.messages import ProtocolMessages from hathor.p2p.sync_agent import SyncAgent from hathor.p2p.sync_v2.mempool import SyncMempoolManager @@ -39,7 +39,6 @@ if TYPE_CHECKING: from hathor.p2p.protocol import HathorProtocol -settings = HathorSettings() logger = get_logger() MAX_GET_TRANSACTIONS_BFS_LEN: int = 8 @@ -66,6 +65,7 @@ def __init__(self, protocol: 'HathorProtocol', reactor: Optional[Reactor] = None :param reactor: Reactor to schedule later calls. (default=twisted.internet.reactor) :type reactor: Reactor """ + self._settings = get_settings() self.protocol = protocol self.manager = protocol.node self.tx_storage = protocol.node.tx_storage @@ -85,7 +85,7 @@ def __init__(self, protocol: 'HathorProtocol', reactor: Optional[Reactor] = None # Extra self._blk_size = 0 - self._blk_end_hash = settings.GENESIS_BLOCK_HASH + self._blk_end_hash = self._settings.GENESIS_BLOCK_HASH self._blk_max_quantity = 0 # indicates whether we're receiving a stream from the peer @@ -319,7 +319,7 @@ def run_sync_transactions(self) -> None: # Start with the last received block and find the best block full validated in its chain block = self._last_received_block if block is None: - block = cast(Block, self.tx_storage.get_genesis(settings.GENESIS_BLOCK_HASH)) + block = cast(Block, self.tx_storage.get_genesis(self._settings.GENESIS_BLOCK_HASH)) else: with self.tx_storage.allow_partially_validated_context(): while not block.get_metadata().validation.is_valid(): diff --git a/hathor/p2p/utils.py b/hathor/p2p/utils.py index 745ab05ee..33b633d34 100644 --- a/hathor/p2p/utils.py +++ b/hathor/p2p/utils.py @@ -28,13 +28,11 @@ from twisted.internet.defer import inlineCallbacks from twisted.internet.interfaces import IAddress -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.indexes.height_index import HeightInfo from hathor.p2p.peer_discovery import DNSPeerDiscovery from hathor.transaction.genesis import GENESIS_HASH -settings = HathorSettings() - def discover_hostname() -> Optional[str]: """ Try to discover your hostname. It is a synchonous operation and @@ -83,6 +81,7 @@ def get_genesis_short_hash() -> str: def get_settings_hello_dict() -> dict[str, Any]: """ Return a dict of settings values that must be validated in the hello state """ + settings = get_settings() settings_dict = {} for key in settings.P2P_SETTINGS_HASH_FIELDS: value = getattr(settings, key) diff --git a/hathor/prometheus.py b/hathor/prometheus.py index 8b3bd51b8..6bd9637d1 100644 --- a/hathor/prometheus.py +++ b/hathor/prometheus.py @@ -18,14 +18,12 @@ from prometheus_client import CollectorRegistry, Gauge, write_to_textfile from twisted.internet.task import LoopingCall -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.util import reactor if TYPE_CHECKING: from hathor.metrics import Metrics -settings = HathorSettings() - # Define prometheus metrics and it's explanation METRIC_INFO = { 'transactions': 'Number of transactions', @@ -79,6 +77,7 @@ def __init__(self, metrics: 'Metrics', path: str, filename: str = 'hathor.prom', :param filename: Name of the prometheus file (must end in .prom) :type filename: str """ + self._settings = get_settings() self.metrics = metrics self.metrics_prefix = metrics_prefix @@ -99,7 +98,7 @@ def __init__(self, metrics: 'Metrics', path: str, filename: str = 'hathor.prom', self.running: bool = False # Interval in which the write data method will be called (in seconds) - self.call_interval: int = settings.PROMETHEUS_WRITE_INTERVAL + self.call_interval: int = self._settings.PROMETHEUS_WRITE_INTERVAL # A timer to periodically write data to prometheus self._lc_write_data = LoopingCall(self._write_data) diff --git a/hathor/simulator/fake_connection.py b/hathor/simulator/fake_connection.py index 5f7581611..663103ff6 100644 --- a/hathor/simulator/fake_connection.py +++ b/hathor/simulator/fake_connection.py @@ -20,13 +20,10 @@ from twisted.internet.address import HostnameAddress from twisted.internet.testing import StringTransport -from hathor.conf import HathorSettings - if TYPE_CHECKING: from hathor.manager import HathorManager from hathor.p2p.peer_id import PeerId -settings = HathorSettings() logger = get_logger() diff --git a/hathor/simulator/miner/geometric_miner.py b/hathor/simulator/miner/geometric_miner.py index 53a0b8c0d..5a2173287 100644 --- a/hathor/simulator/miner/geometric_miner.py +++ b/hathor/simulator/miner/geometric_miner.py @@ -15,7 +15,7 @@ import math from typing import TYPE_CHECKING, Optional -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.manager import HathorEvents from hathor.simulator.miner.abstract_miner import AbstractMiner from hathor.util import Random @@ -25,8 +25,6 @@ from hathor.pubsub import EventArguments from hathor.transaction import Block -settings = HathorSettings() - class GeometricMiner(AbstractMiner): """ Simulate block mining with actually solving the block. It is supposed to be used @@ -46,6 +44,7 @@ def __init__( blocks than values provided, 0 is used. """ super().__init__(manager, rng) + self._settings = get_settings() self._hashpower = hashpower self._signal_bits = signal_bits or [] @@ -107,9 +106,9 @@ def _schedule_next_block(self): else: dt = 60 - if dt > settings.WEIGHT_DECAY_ACTIVATE_DISTANCE: + if dt > self._settings.WEIGHT_DECAY_ACTIVATE_DISTANCE: self._block = None - dt = settings.WEIGHT_DECAY_ACTIVATE_DISTANCE + dt = self._settings.WEIGHT_DECAY_ACTIVATE_DISTANCE if self._delayed_call and self._delayed_call.active(): self._delayed_call.cancel() diff --git a/hathor/simulator/simulator.py b/hathor/simulator/simulator.py index 9ecc805df..cae937e03 100644 --- a/hathor/simulator/simulator.py +++ b/hathor/simulator/simulator.py @@ -21,7 +21,7 @@ from structlog import get_logger from hathor.builder import BuildArtifacts, Builder -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.daa import TestMode, _set_test_mode from hathor.manager import HathorManager from hathor.p2p.peer_id import PeerId @@ -116,7 +116,7 @@ def __init__(self, seed: Optional[int] = None): seed = secrets.randbits(64) self.seed = seed self.rng = Random(self.seed) - self.settings = HathorSettings() + self.settings = get_settings() self._network = 'testnet' self._clock = MemoryReactorHeapClock() self._peers: OrderedDict[str, HathorManager] = OrderedDict() diff --git a/hathor/simulator/tx_generator.py b/hathor/simulator/tx_generator.py index 27041ac3c..6bb76c1a8 100644 --- a/hathor/simulator/tx_generator.py +++ b/hathor/simulator/tx_generator.py @@ -18,7 +18,7 @@ from structlog import get_logger from hathor import daa -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.transaction.exceptions import RewardLocked from hathor.util import Random from hathor.wallet.exceptions import InsufficientFunds @@ -28,7 +28,6 @@ from hathor.manager import HathorManager from hathor.transaction import Transaction -settings = HathorSettings() logger = get_logger() @@ -45,6 +44,7 @@ def __init__(self, manager: 'HathorManager', rng: Random, *, :param: rate: Number of transactions per second :param: hashpower: Number of hashes per second """ + self._settings = get_settings() self.manager = manager # List of addresses to send tokens. If this list is empty, tokens will be sent to an address @@ -101,7 +101,7 @@ def schedule_next_transaction(self): def new_tx_step1(self): """ Generate a new transaction and schedule the mining part of the transaction. """ - balance = self.manager.wallet.balance[settings.HATHOR_TOKEN_UID] + balance = self.manager.wallet.balance[self._settings.HATHOR_TOKEN_UID] if balance.available == 0 and self.ignore_no_funds: self.delayedcall = self.clock.callLater(0, self.schedule_next_transaction) return diff --git a/hathor/stratum/stratum.py b/hathor/stratum/stratum.py index bc3d79492..6abc2dfbd 100644 --- a/hathor/stratum/stratum.py +++ b/hathor/stratum/stratum.py @@ -33,7 +33,7 @@ from twisted.protocols.basic import LineReceiver from twisted.python.failure import Failure -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.crypto.util import decode_address from hathor.exception import InvalidNewTransaction from hathor.p2p.utils import format_address @@ -49,7 +49,6 @@ from hathor.manager import HathorManager # noqa: F401 logger = get_logger() -settings = HathorSettings() def valid_uuid(uuid: Any) -> bool: @@ -364,6 +363,7 @@ class StratumProtocol(JSONRPC): def __init__(self, factory: 'StratumFactory', manager: 'HathorManager', address: IAddress, id_generator: Optional[Callable[[], Iterator[Union[str, int]]]] = lambda: count()): + self._settings = get_settings() self.log = logger.new(address=address) self.factory = factory self.manager = manager @@ -374,7 +374,7 @@ def __init__(self, factory: 'StratumFactory', manager: 'HathorManager', address: self.miner_id = None self.miner_address = None self.job_ids = [] - self.mine_txs = settings.STRATUM_MINE_TXS_DEFAULT + self.mine_txs = self._settings.STRATUM_MINE_TXS_DEFAULT self.estimated_hash_rate = 0.0 self.completed_jobs = 0 self.connection_start_time = 0 @@ -665,7 +665,8 @@ def create_job_tx(self, jobid: UUID) -> BaseTransaction: assert self.miner_id is not None # Only get first 32 bytes of peer_id because block data is limited to 100 bytes - data = '{}-{}-{}'.format(peer_id[:32], self.miner_id.hex, jobid.hex).encode()[:settings.BLOCK_DATA_MAX_SIZE] + data = '{}-{}-{}'.format(peer_id[:32], self.miner_id.hex, jobid.hex).encode() + data = data[:self._settings.BLOCK_DATA_MAX_SIZE] block = self.manager.generate_mining_block(data=data, address=self.miner_address, merge_mined=self.merged_mining) self.log.debug('prepared block for mining', block=block) @@ -687,7 +688,7 @@ def calculate_share_weight(self) -> float: :rtype: float """ if len(self.job_ids) <= 1: - return settings.MIN_BLOCK_WEIGHT + return self._settings.MIN_BLOCK_WEIGHT mn = self.jobs[self.job_ids[0]].tx.timestamp mx = self.jobs[self.job_ids[-1]].tx.timestamp @@ -701,7 +702,7 @@ def calculate_share_weight(self) -> float: hash_rate = acc_weight - log(dt, 2) self.estimated_hash_rate = hash_rate share_weight = hash_rate + log(self.AVERAGE_JOB_TIME, 2) - share_weight = max(share_weight, settings.MIN_SHARE_WEIGHT) + share_weight = max(share_weight, self._settings.MIN_SHARE_WEIGHT) return share_weight def get_stats(self) -> MinerStatistics: diff --git a/hathor/transaction/__init__.py b/hathor/transaction/__init__.py index 9c98f7785..9b803cbd2 100644 --- a/hathor/transaction/__init__.py +++ b/hathor/transaction/__init__.py @@ -14,8 +14,6 @@ from hathor.transaction.aux_pow import BitcoinAuxPow from hathor.transaction.base_transaction import ( - MAX_NUM_INPUTS, - MAX_NUM_OUTPUTS, MAX_OUTPUT_VALUE, BaseTransaction, TxInput, @@ -38,8 +36,6 @@ 'TxInput', 'TxOutput', 'TxVersion', - 'MAX_NUM_INPUTS', - 'MAX_NUM_OUTPUTS', 'MAX_OUTPUT_VALUE', 'sum_weights', ] diff --git a/hathor/transaction/base_transaction.py b/hathor/transaction/base_transaction.py index ef8350fde..f4a3eb358 100644 --- a/hathor/transaction/base_transaction.py +++ b/hathor/transaction/base_transaction.py @@ -27,7 +27,7 @@ from structlog import get_logger from hathor.checkpoint import Checkpoint -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.transaction.exceptions import ( DuplicatedParents, IncorrectParents, @@ -54,11 +54,8 @@ from hathor.transaction.storage import TransactionStorage # noqa: F401 logger = get_logger() -settings = HathorSettings() MAX_NONCE = 2**32 -MAX_NUM_INPUTS = settings.MAX_NUM_INPUTS -MAX_NUM_OUTPUTS = settings.MAX_NUM_OUTPUTS MAX_OUTPUT_VALUE = 2**63 # max value (inclusive) that is possible to encode: 9223372036854775808 ~= 9.22337e+18 _MAX_OUTPUT_VALUE_32 = 2**31 - 1 # max value (inclusive) before having to use 8 bytes: 2147483647 ~= 2.14748e+09 @@ -184,6 +181,7 @@ def __init__(self, assert signal_bits <= _ONE_BYTE, f'signal_bits {hex(signal_bits)} must not be larger than one byte' assert version <= _ONE_BYTE, f'version {hex(version)} must not be larger than one byte' + self._settings = get_settings() self.nonce = nonce self.timestamp = timestamp or int(time.time()) self.signal_bits = signal_bits @@ -560,7 +558,7 @@ def _mark_partially_validated(self) -> None: """ tx_meta = self.get_metadata() assert not tx_meta.validation.is_fully_connected() - tx_meta.add_voided_by(settings.PARTIALLY_VALIDATED_ID) + tx_meta.add_voided_by(self._settings.PARTIALLY_VALIDATED_ID) def _unmark_partially_validated(self) -> None: """ This function is used to remove the partially-validated mark from the voided-by metadata. @@ -570,7 +568,7 @@ def _unmark_partially_validated(self) -> None: """ tx_meta = self.get_metadata() assert tx_meta.validation.is_fully_connected() - tx_meta.del_voided_by(settings.PARTIALLY_VALIDATED_ID) + tx_meta.del_voided_by(self._settings.PARTIALLY_VALIDATED_ID) @abstractmethod def verify_checkpoint(self, checkpoints: list[Checkpoint]) -> None: @@ -631,7 +629,7 @@ def verify_parents(self) -> None: if parent.is_block: if self.is_block and not parent.is_genesis: - if self.timestamp - parent.timestamp > settings.MAX_DISTANCE_BETWEEN_BLOCKS: + if self.timestamp - parent.timestamp > self._settings.MAX_DISTANCE_BETWEEN_BLOCKS: raise TimestampError('Distance between blocks is too big' ' ({} seconds)'.format(self.timestamp - parent.timestamp)) if my_parents_txs > 0: @@ -684,7 +682,7 @@ def verify_pow(self, override_weight: Optional[float] = None) -> None: def verify_number_of_outputs(self) -> None: """Verify number of outputs does not exceeds the limit""" - if len(self.outputs) > MAX_NUM_OUTPUTS: + if len(self.outputs) > self._settings.MAX_NUM_OUTPUTS: raise TooManyOutputs('Maximum number of outputs exceeded') def verify_sigops_output(self) -> None: @@ -696,7 +694,7 @@ def verify_sigops_output(self) -> None: for tx_output in self.outputs: n_txops += get_sigops_count(tx_output.script) - if n_txops > settings.MAX_TX_SIGOPS_OUTPUT: + if n_txops > self._settings.MAX_TX_SIGOPS_OUTPUT: raise TooManySigOps('TX[{}]: Maximum number of sigops for all outputs exceeded ({})'.format( self.hash_hex, n_txops)) @@ -719,9 +717,9 @@ def verify_outputs(self) -> None: raise InvalidOutputValue('Output value must be a positive integer. Value: {} and index: {}'.format( output.value, index)) - if len(output.script) > settings.MAX_OUTPUT_SCRIPT_SIZE: + if len(output.script) > self._settings.MAX_OUTPUT_SCRIPT_SIZE: raise InvalidOutputScriptSize('size: {} and max-size: {}'.format( - len(output.script), settings.MAX_OUTPUT_SCRIPT_SIZE + len(output.script), self._settings.MAX_OUTPUT_SCRIPT_SIZE )) def resolve(self, update_time: bool = False) -> bool: @@ -912,7 +910,7 @@ def reset_metadata(self) -> None: self._metadata.voided_by = set() else: self._metadata.validation = ValidationState.INITIAL - self._metadata.voided_by = {settings.PARTIALLY_VALIDATED_ID} + self._metadata.voided_by = {self._settings.PARTIALLY_VALIDATED_ID} self._metadata._tx_ref = weakref.ref(self) self._update_height_metadata() diff --git a/hathor/transaction/block.py b/hathor/transaction/block.py index 08fe7c69a..8ed354842 100644 --- a/hathor/transaction/block.py +++ b/hathor/transaction/block.py @@ -20,7 +20,6 @@ from hathor import daa from hathor.checkpoint import Checkpoint -from hathor.conf import HathorSettings from hathor.feature_activation.feature import Feature from hathor.feature_activation.model.feature_state import FeatureState from hathor.profiler import get_cpu_profiler @@ -41,7 +40,6 @@ if TYPE_CHECKING: from hathor.transaction.storage import TransactionStorage # noqa: F401 -settings = HathorSettings() cpu = get_cpu_profiler() # Signal bits (B), version (B), outputs len (B) @@ -142,7 +140,7 @@ def _get_previous_feature_activation_bit_counts(self) -> list[int]: Returns the feature_activation_bit_counts metadata attribute from the parent block, or no previous counts if this is a boundary block. """ - evaluation_interval = settings.FEATURE_ACTIVATION.evaluation_interval + evaluation_interval = self._settings.FEATURE_ACTIVATION.evaluation_interval is_boundary_block = self.calculate_height() % evaluation_interval == 0 if is_boundary_block: @@ -297,7 +295,7 @@ def get_token_uid(self, index: int) -> bytes: :rtype: bytes """ assert index == 0 - return settings.HATHOR_TOKEN_UID + return self._settings.HATHOR_TOKEN_UID # TODO: maybe introduce convention on serialization methods names (e.g. to_json vs get_struct) def to_json(self, decode_script: bool = False, include_metadata: bool = False) -> dict[str, Any]: @@ -348,7 +346,7 @@ def verify_checkpoint(self, checkpoints: list[Checkpoint]) -> None: def verify_weight(self) -> None: """Validate minimum block difficulty.""" block_weight = daa.calculate_block_difficulty(self) - if self.weight < block_weight - settings.WEIGHT_TOL: + if self.weight < block_weight - self._settings.WEIGHT_TOL: raise WeightError(f'Invalid new block {self.hash_hex}: weight ({self.weight}) is ' f'smaller than the minimum weight ({block_weight})') @@ -382,7 +380,7 @@ def verify_outputs(self) -> None: raise BlockWithTokensError('in output: {}'.format(output.to_human_readable())) def verify_data(self) -> None: - if len(self.data) > settings.BLOCK_DATA_MAX_SIZE: + if len(self.data) > self._settings.BLOCK_DATA_MAX_SIZE: raise TransactionDataError('block data has {} bytes'.format(len(self.data))) def verify_without_storage(self) -> None: @@ -442,14 +440,13 @@ def _get_feature_activation_bit_list(self) -> list[int]: bitmask = self._get_feature_activation_bitmask() bits = self.signal_bits & bitmask - bit_list = get_bit_list(bits, min_size=settings.FEATURE_ACTIVATION.max_signal_bits) + bit_list = get_bit_list(bits, min_size=self._settings.FEATURE_ACTIVATION.max_signal_bits) return bit_list - @classmethod - def _get_feature_activation_bitmask(cls) -> int: + def _get_feature_activation_bitmask(self) -> int: """Returns the bitmask that gets feature activation bits from signal bits.""" - bitmask = (1 << settings.FEATURE_ACTIVATION.max_signal_bits) - 1 + bitmask = (1 << self._settings.FEATURE_ACTIVATION.max_signal_bits) - 1 return bitmask diff --git a/hathor/transaction/token_creation_tx.py b/hathor/transaction/token_creation_tx.py index c70ca761c..f134b9896 100644 --- a/hathor/transaction/token_creation_tx.py +++ b/hathor/transaction/token_creation_tx.py @@ -15,15 +15,12 @@ from struct import error as StructError, pack from typing import Any, Optional -from hathor.conf import HathorSettings from hathor.transaction.base_transaction import TxInput, TxOutput, TxVersion from hathor.transaction.exceptions import InvalidToken, TransactionDataError from hathor.transaction.storage import TransactionStorage # noqa: F401 from hathor.transaction.transaction import TokenInfo, Transaction from hathor.transaction.util import VerboseCallback, clean_token_string, int_to_bytes, unpack, unpack_len -settings = HathorSettings() - # Signal bits (B), version (B), inputs len (B), outputs len (B) _FUNDS_FORMAT_STRING = '!BBBB' @@ -259,15 +256,15 @@ def verify_token_info(self) -> None: """ name_len = len(self.token_name) symbol_len = len(self.token_symbol) - if name_len == 0 or name_len > settings.MAX_LENGTH_TOKEN_NAME: + if name_len == 0 or name_len > self._settings.MAX_LENGTH_TOKEN_NAME: raise TransactionDataError('Invalid token name length ({})'.format(name_len)) - if symbol_len == 0 or symbol_len > settings.MAX_LENGTH_TOKEN_SYMBOL: + if symbol_len == 0 or symbol_len > self._settings.MAX_LENGTH_TOKEN_SYMBOL: raise TransactionDataError('Invalid token symbol length ({})'.format(symbol_len)) # Can't create token with hathor name or symbol - if clean_token_string(self.token_name) == clean_token_string(settings.HATHOR_TOKEN_NAME): + if clean_token_string(self.token_name) == clean_token_string(self._settings.HATHOR_TOKEN_NAME): raise TransactionDataError('Invalid token name ({})'.format(self.token_name)) - if clean_token_string(self.token_symbol) == clean_token_string(settings.HATHOR_TOKEN_SYMBOL): + if clean_token_string(self.token_symbol) == clean_token_string(self._settings.HATHOR_TOKEN_SYMBOL): raise TransactionDataError('Invalid token symbol ({})'.format(self.token_symbol)) diff --git a/hathor/transaction/transaction.py b/hathor/transaction/transaction.py index 90150b7a0..98d4bcfc2 100644 --- a/hathor/transaction/transaction.py +++ b/hathor/transaction/transaction.py @@ -19,10 +19,9 @@ from hathor import daa from hathor.checkpoint import Checkpoint -from hathor.conf import HathorSettings from hathor.exception import InvalidNewTransaction from hathor.profiler import get_cpu_profiler -from hathor.transaction import MAX_NUM_INPUTS, BaseTransaction, Block, TxInput, TxOutput, TxVersion +from hathor.transaction import BaseTransaction, Block, TxInput, TxOutput, TxVersion from hathor.transaction.base_transaction import TX_HASH_SIZE from hathor.transaction.exceptions import ( ConflictingInputs, @@ -48,7 +47,6 @@ if TYPE_CHECKING: from hathor.transaction.storage import TransactionStorage # noqa: F401 -settings = HathorSettings() cpu = get_cpu_profiler() # Signal bits (B), version (B), token uids len (B) and inputs len (B), outputs len (B). @@ -155,7 +153,7 @@ def _calculate_my_min_height(self) -> int: """ Calculates min height derived from own spent block rewards""" min_height = 0 for blk in self.iter_spent_rewards(): - min_height = max(min_height, blk.get_height() + settings.REWARD_SPEND_MIN_BLOCKS + 1) + min_height = max(min_height, blk.get_height() + self._settings.REWARD_SPEND_MIN_BLOCKS + 1) return min_height def get_funds_fields_from_struct(self, buf: bytes, *, verbose: VerboseCallback = None) -> bytes: @@ -278,7 +276,7 @@ def get_token_uid(self, index: int) -> TokenUid: :return: the token uid """ if index == 0: - return settings.HATHOR_TOKEN_UID + return self._settings.HATHOR_TOKEN_UID return self.tokens[index - 1] def to_json(self, decode_script: bool = False, include_metadata: bool = False) -> dict[str, Any]: @@ -322,11 +320,11 @@ def verify_parents_basic(self) -> None: def verify_weight(self) -> None: """Validate minimum tx difficulty.""" min_tx_weight = daa.minimum_tx_weight(self) - max_tx_weight = min_tx_weight + settings.MAX_TX_WEIGHT_DIFF - if self.weight < min_tx_weight - settings.WEIGHT_TOL: + max_tx_weight = min_tx_weight + self._settings.MAX_TX_WEIGHT_DIFF + if self.weight < min_tx_weight - self._settings.WEIGHT_TOL: raise WeightError(f'Invalid new tx {self.hash_hex}: weight ({self.weight}) is ' f'smaller than the minimum weight ({min_tx_weight})') - elif min_tx_weight > settings.MAX_TX_WEIGHT_DIFF_ACTIVATION and self.weight > max_tx_weight: + elif min_tx_weight > self._settings.MAX_TX_WEIGHT_DIFF_ACTIVATION and self.weight > max_tx_weight: raise WeightError(f'Invalid new tx {self.hash_hex}: weight ({self.weight}) is ' f'greater than the maximum allowed ({max_tx_weight})') @@ -375,7 +373,7 @@ def verify_without_storage(self) -> None: def verify_number_of_inputs(self) -> None: """Verify number of inputs is in a valid range""" - if len(self.inputs) > MAX_NUM_INPUTS: + if len(self.inputs) > self._settings.MAX_NUM_INPUTS: raise TooManyInputs('Maximum number of inputs exceeded') if len(self.inputs) == 0: @@ -399,7 +397,7 @@ def verify_sigops_input(self) -> None: tx_input.tx_id.hex(), tx_input.index)) n_txops += get_sigops_count(tx_input.data, spent_tx.outputs[tx_input.index].script) - if n_txops > settings.MAX_TX_SIGOPS_INPUT: + if n_txops > self._settings.MAX_TX_SIGOPS_INPUT: raise TooManySigOps( 'TX[{}]: Max number of sigops for inputs exceeded ({})'.format(self.hash_hex, n_txops)) @@ -424,7 +422,7 @@ def get_token_info_from_inputs(self) -> dict[TokenUid, TokenInfo]: # add HTR to token dict due to tx melting tokens: there might be an HTR output without any # input or authority. If we don't add it, an error will be raised when iterating through # the outputs of such tx (error: 'no token creation and no inputs for token 00') - token_dict[settings.HATHOR_TOKEN_UID] = TokenInfo(0, False, False) + token_dict[self._settings.HATHOR_TOKEN_UID] = TokenInfo(0, False, False) for tx_input in self.inputs: spent_tx = self.get_spent_tx(tx_input) @@ -486,7 +484,7 @@ def check_authorities_and_deposit(self, token_dict: dict[TokenUid, TokenInfo]) - withdraw = 0 deposit = 0 for token_uid, token_info in token_dict.items(): - if token_uid == settings.HATHOR_TOKEN_UID: + if token_uid == self._settings.HATHOR_TOKEN_UID: continue if token_info.amount == 0: @@ -507,7 +505,7 @@ def check_authorities_and_deposit(self, token_dict: dict[TokenUid, TokenInfo]) - # check whether the deposit/withdraw amount is correct htr_expected_amount = withdraw - deposit - htr_info = token_dict[settings.HATHOR_TOKEN_UID] + htr_info = token_dict[self._settings.HATHOR_TOKEN_UID] if htr_info.amount != htr_expected_amount: raise InputOutputMismatch('HTR balance is different than expected. (amount={}, expected={})'.format( htr_info.amount, @@ -541,9 +539,9 @@ def verify_inputs(self, *, skip_script: bool = False) -> None: spent_outputs: set[tuple[VertexId, int]] = set() for input_tx in self.inputs: - if len(input_tx.data) > settings.MAX_INPUT_DATA_SIZE: + if len(input_tx.data) > self._settings.MAX_INPUT_DATA_SIZE: raise InvalidInputDataSize('size: {} and max-size: {}'.format( - len(input_tx.data), settings.MAX_INPUT_DATA_SIZE + len(input_tx.data), self._settings.MAX_INPUT_DATA_SIZE )) try: @@ -610,7 +608,7 @@ def _spent_reward_needed_height(self, block: Block) -> int: assert isinstance(best_height, int) spent_height = block.get_height() spend_blocks = best_height - spent_height - needed_height = settings.REWARD_SPEND_MIN_BLOCKS - spend_blocks + needed_height = self._settings.REWARD_SPEND_MIN_BLOCKS - spend_blocks return max(needed_height, 0) def verify_script(self, input_tx: TxInput, spent_tx: BaseTransaction) -> None: diff --git a/tests/tx/test_tx.py b/tests/tx/test_tx.py index 7c3f66e49..0a18106d3 100644 --- a/tests/tx/test_tx.py +++ b/tests/tx/test_tx.py @@ -3,10 +3,9 @@ from math import isinf, isnan from hathor import daa -from hathor.conf import HathorSettings from hathor.crypto.util import decode_address, get_address_from_public_key, get_private_key_from_bytes from hathor.daa import TestMode, _set_test_mode -from hathor.transaction import MAX_NUM_INPUTS, MAX_NUM_OUTPUTS, MAX_OUTPUT_VALUE, Block, Transaction, TxInput, TxOutput +from hathor.transaction import MAX_OUTPUT_VALUE, Block, Transaction, TxInput, TxOutput from hathor.transaction.exceptions import ( BlockWithInputs, ConflictingInputs, @@ -41,8 +40,6 @@ get_genesis_key, ) -settings = HathorSettings() - class BaseTransactionTest(unittest.TestCase): __test__ = False @@ -129,7 +126,7 @@ def test_too_many_inputs(self): random_bytes = bytes.fromhex('0000184e64683b966b4268f387c269915cc61f6af5329823a93e3696cb0fe902') _input = TxInput(random_bytes, 0, random_bytes) - inputs = [_input] * (MAX_NUM_INPUTS + 1) + inputs = [_input] * (self._settings.MAX_NUM_INPUTS + 1) tx = Transaction(inputs=inputs, storage=self.tx_storage) @@ -146,7 +143,7 @@ def test_too_many_outputs(self): random_bytes = bytes.fromhex('0000184e64683b966b4268f387c269915cc61f6af5329823a93e3696cb0fe902') output = TxOutput(1, random_bytes) - outputs = [output] * (MAX_NUM_OUTPUTS + 1) + outputs = [output] * (self._settings.MAX_NUM_OUTPUTS + 1) tx = Transaction(outputs=outputs, storage=self.tx_storage) @@ -351,7 +348,6 @@ def test_merge_mined_long_merkle_path(self): b.verify_aux_pow() def test_block_outputs(self): - from hathor.transaction import MAX_NUM_OUTPUTS from hathor.transaction.exceptions import TooManyOutputs # a block should have no more than MAX_NUM_OUTPUTS outputs @@ -359,7 +355,7 @@ def test_block_outputs(self): address = get_address_from_public_key(self.genesis_public_key) output_script = P2PKH.create_output_script(address) - tx_outputs = [TxOutput(100, output_script)] * (MAX_NUM_OUTPUTS + 1) + tx_outputs = [TxOutput(100, output_script)] * (self._settings.MAX_NUM_OUTPUTS + 1) block = Block( nonce=100, @@ -535,7 +531,7 @@ def test_tx_weight_too_high(self): tx = Transaction(weight=1, inputs=inputs, outputs=outputs, parents=parents, storage=self.tx_storage, timestamp=self.last_block.timestamp + 1) tx.weight = daa.minimum_tx_weight(tx) - tx.weight += settings.MAX_TX_WEIGHT_DIFF + 0.1 + tx.weight += self._settings.MAX_TX_WEIGHT_DIFF + 0.1 tx.update_hash() with self.assertRaises(WeightError): tx.verify_weight() @@ -656,7 +652,7 @@ def test_propagation_error(self): # 4. propagate block from the future block = manager.generate_mining_block() - block.timestamp = int(self.clock.seconds()) + settings.MAX_FUTURE_TIMESTAMP_ALLOWED + 100 + block.timestamp = int(self.clock.seconds()) + self._settings.MAX_FUTURE_TIMESTAMP_ALLOWED + 100 block.resolve(update_time=False) self.assertFalse(manager.propagate_tx(block)) @@ -709,7 +705,7 @@ def test_tx_methods(self): # Validate maximum distance between blocks block = blocks[0] block2 = blocks[1] - block2.timestamp = block.timestamp + settings.MAX_DISTANCE_BETWEEN_BLOCKS + block2.timestamp = block.timestamp + self._settings.MAX_DISTANCE_BETWEEN_BLOCKS block2.verify_parents() block2.timestamp += 1 with self.assertRaises(TimestampError): @@ -886,7 +882,7 @@ def _test_txout_script_limit(self, offset): _input = TxInput(genesis_block.hash, 0, b'') value = genesis_block.outputs[0].value - script = b'*' * (settings.MAX_OUTPUT_SCRIPT_SIZE + offset) + script = b'*' * (self._settings.MAX_OUTPUT_SCRIPT_SIZE + offset) _output = TxOutput(value, script) tx = Transaction(inputs=[_input], outputs=[_output], storage=self.tx_storage) @@ -902,7 +898,7 @@ def test_txout_script_limit_success(self): def _test_txin_data_limit(self, offset): genesis_block = self.genesis_blocks[0] - data = b'*' * (settings.MAX_INPUT_DATA_SIZE + offset) + data = b'*' * (self._settings.MAX_INPUT_DATA_SIZE + offset) _input = TxInput(genesis_block.hash, 0, data) value = genesis_block.outputs[0].value @@ -1037,7 +1033,7 @@ def test_sigops_output_single_above_limit(self) -> None: value = genesis_block.outputs[0].value - 1 _input = TxInput(genesis_block.hash, 0, b'') - hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_OUTPUT + 1) + hscript = create_script_with_sigops(self._settings.MAX_TX_SIGOPS_OUTPUT + 1) output1 = TxOutput(value, hscript) tx = Transaction(inputs=[_input], outputs=[output1], storage=self.tx_storage) tx.update_hash() @@ -1051,7 +1047,7 @@ def test_sigops_output_multi_above_limit(self) -> None: _input = TxInput(genesis_block.hash, 0, b'') num_outputs = 5 - hscript = create_script_with_sigops((settings.MAX_TX_SIGOPS_OUTPUT + num_outputs) // num_outputs) + hscript = create_script_with_sigops((self._settings.MAX_TX_SIGOPS_OUTPUT + num_outputs) // num_outputs) output2 = TxOutput(value, hscript) tx = Transaction(inputs=[_input], outputs=[output2]*num_outputs, storage=self.tx_storage) tx.update_hash() @@ -1063,7 +1059,7 @@ def test_sigops_output_single_below_limit(self) -> None: value = genesis_block.outputs[0].value - 1 _input = TxInput(genesis_block.hash, 0, b'') - hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_OUTPUT - 1) + hscript = create_script_with_sigops(self._settings.MAX_TX_SIGOPS_OUTPUT - 1) output3 = TxOutput(value, hscript) tx = Transaction(inputs=[_input], outputs=[output3], storage=self.tx_storage) tx.update_hash() @@ -1075,7 +1071,7 @@ def test_sigops_output_multi_below_limit(self) -> None: _input = TxInput(genesis_block.hash, 0, b'') num_outputs = 5 - hscript = create_script_with_sigops((settings.MAX_TX_SIGOPS_OUTPUT - 1) // num_outputs) + hscript = create_script_with_sigops((self._settings.MAX_TX_SIGOPS_OUTPUT - 1) // num_outputs) output4 = TxOutput(value, hscript) tx = Transaction(inputs=[_input], outputs=[output4]*num_outputs, storage=self.tx_storage) tx.update_hash() @@ -1088,7 +1084,7 @@ def test_sigops_input_single_above_limit(self) -> None: script = P2PKH.create_output_script(address) _output = TxOutput(value, script) - hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_INPUT + 1) + hscript = create_script_with_sigops(self._settings.MAX_TX_SIGOPS_INPUT + 1) input1 = TxInput(genesis_block.hash, 0, hscript) tx = Transaction(inputs=[input1], outputs=[_output], storage=self.tx_storage) tx.update_hash() @@ -1103,7 +1099,7 @@ def test_sigops_input_multi_above_limit(self) -> None: _output = TxOutput(value, script) num_inputs = 5 - hscript = create_script_with_sigops((settings.MAX_TX_SIGOPS_INPUT + num_inputs) // num_inputs) + hscript = create_script_with_sigops((self._settings.MAX_TX_SIGOPS_INPUT + num_inputs) // num_inputs) input2 = TxInput(genesis_block.hash, 0, hscript) tx = Transaction(inputs=[input2]*num_inputs, outputs=[_output], storage=self.tx_storage) tx.update_hash() @@ -1117,7 +1113,7 @@ def test_sigops_input_single_below_limit(self) -> None: script = P2PKH.create_output_script(address) _output = TxOutput(value, script) - hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_INPUT - 1) + hscript = create_script_with_sigops(self._settings.MAX_TX_SIGOPS_INPUT - 1) input3 = TxInput(genesis_block.hash, 0, hscript) tx = Transaction(inputs=[input3], outputs=[_output], storage=self.tx_storage) tx.update_hash() @@ -1131,7 +1127,7 @@ def test_sigops_input_multi_below_limit(self) -> None: _output = TxOutput(value, script) num_inputs = 5 - hscript = create_script_with_sigops((settings.MAX_TX_SIGOPS_INPUT - 1) // num_inputs) + hscript = create_script_with_sigops((self._settings.MAX_TX_SIGOPS_INPUT - 1) // num_inputs) input4 = TxInput(genesis_block.hash, 0, hscript) tx = Transaction(inputs=[input4]*num_inputs, outputs=[_output], storage=self.tx_storage) tx.update_hash() diff --git a/tests/unittest.py b/tests/unittest.py index 9eab1e9c4..e9ccfdbb3 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -11,6 +11,7 @@ from hathor.builder import BuildArtifacts, Builder from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.daa import TestMode, _set_test_mode from hathor.p2p.peer_id import PeerId from hathor.p2p.sync_version import SyncVersion @@ -113,6 +114,7 @@ def setUp(self): self.log.debug('set seed', seed=self.seed) self.rng = Random(self.seed) self._pending_cleanups = [] + self._settings = get_settings() def tearDown(self): self.clean_tmpdirs() From 87ae52e781210e6cbdb2cefdd271d684ef8860a6 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Tue, 19 Sep 2023 13:56:20 -0300 Subject: [PATCH 07/26] refactor: move get settings [part 2] (#769) --- hathor/builder/builder.py | 4 ++-- hathor/builder/cli_builder.py | 5 ++--- hathor/builder/resources_builder.py | 4 ++-- hathor/cli/db_export.py | 8 ++++---- hathor/cli/events_simulator/scenario.py | 4 ++-- hathor/cli/nginx_config.py | 4 ++-- hathor/cli/run_node.py | 8 ++++---- hathor/consensus/block_consensus.py | 14 ++++++------- hathor/consensus/consensus.py | 12 +++++------ hathor/consensus/context.py | 2 -- hathor/consensus/transaction_consensus.py | 18 ++++++++-------- hathor/crypto/util.py | 25 ++++++++++++----------- hathor/graphviz.py | 7 +++---- hathor/indexes/rocksdb_height_index.py | 2 -- hathor/indexes/rocksdb_tokens_index.py | 16 +++++++-------- hathor/indexes/rocksdb_utils.py | 6 +++--- hathor/indexes/utxo_index.py | 5 +++-- hathor/merged_mining/coordinator.py | 2 -- hathor/mining/ws.py | 2 -- hathor/p2p/peer_id.py | 19 +++++++++-------- hathor/p2p/protocol.py | 6 +++--- 21 files changed, 84 insertions(+), 89 deletions(-) diff --git a/hathor/builder/builder.py b/hathor/builder/builder.py index 1c83b3494..0773347ed 100644 --- a/hathor/builder/builder.py +++ b/hathor/builder/builder.py @@ -18,7 +18,7 @@ from structlog import get_logger from hathor.checkpoint import Checkpoint -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.conf.settings import HathorSettings as HathorSettingsType from hathor.consensus import ConsensusAlgorithm from hathor.event import EventManager @@ -259,7 +259,7 @@ def set_peer_id(self, peer_id: PeerId) -> 'Builder': def _get_or_create_settings(self) -> HathorSettingsType: if self._settings is None: - self._settings = HathorSettings() + self._settings = get_settings() return self._settings def _get_reactor(self) -> Reactor: diff --git a/hathor/builder/cli_builder.py b/hathor/builder/cli_builder.py index d8760d46e..d71a932a2 100644 --- a/hathor/builder/cli_builder.py +++ b/hathor/builder/cli_builder.py @@ -56,8 +56,7 @@ def check_or_raise(self, condition: bool, message: str) -> None: def create_manager(self, reactor: Reactor) -> HathorManager: import hathor - from hathor.conf import HathorSettings - from hathor.conf.get_settings import get_settings_source + from hathor.conf.get_settings import get_settings, get_settings_source from hathor.daa import TestMode, _set_test_mode from hathor.event.storage import EventMemoryStorage, EventRocksDBStorage, EventStorage from hathor.event.websocket.factory import EventWebsocketFactory @@ -73,7 +72,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager: ) from hathor.util import get_environment_info - settings = HathorSettings() + settings = get_settings() # only used for logging its location settings_source = get_settings_source() diff --git a/hathor/builder/resources_builder.py b/hathor/builder/resources_builder.py index f119b3f42..5fb42ed0a 100644 --- a/hathor/builder/resources_builder.py +++ b/hathor/builder/resources_builder.py @@ -77,7 +77,7 @@ def create_prometheus(self) -> PrometheusMetricsExporter: return prometheus def create_resources(self) -> server.Site: - from hathor.conf import HathorSettings + from hathor.conf.get_settings import get_settings from hathor.debug_resources import ( DebugCrashResource, DebugLogResource, @@ -141,7 +141,7 @@ def create_resources(self) -> server.Site: ) from hathor.websocket import HathorAdminWebsocketFactory, WebsocketStatsResource - settings = HathorSettings() + settings = get_settings() cpu = get_cpu_profiler() # TODO get this from a file. How should we do with the factory? diff --git a/hathor/cli/db_export.py b/hathor/cli/db_export.py index f2018d395..1a13afd9e 100644 --- a/hathor/cli/db_export.py +++ b/hathor/cli/db_export.py @@ -34,8 +34,8 @@ def register_signal_handlers(self) -> None: @classmethod def create_parser(cls) -> ArgumentParser: - from hathor.conf import HathorSettings - settings = HathorSettings() + from hathor.conf.get_settings import get_settings + settings = get_settings() def max_height(arg: str) -> Optional[int]: if arg.lower() == 'checkpoint': @@ -80,8 +80,8 @@ def prepare(self, *, register_resources: bool = True) -> None: self.skip_voided = self._args.export_skip_voided def iter_tx(self) -> Iterator['BaseTransaction']: - from hathor.conf import HathorSettings - settings = HathorSettings() + from hathor.conf.get_settings import get_settings + settings = get_settings() soft_voided_ids = set(settings.SOFT_VOIDED_TX_IDS) for tx in self._iter_tx: diff --git a/hathor/cli/events_simulator/scenario.py b/hathor/cli/events_simulator/scenario.py index db2b6db27..ea8f16528 100644 --- a/hathor/cli/events_simulator/scenario.py +++ b/hathor/cli/events_simulator/scenario.py @@ -51,10 +51,10 @@ def simulate_single_chain_one_block(simulator: 'Simulator', manager: 'HathorMana def simulate_single_chain_blocks_and_transactions(simulator: 'Simulator', manager: 'HathorManager') -> None: from hathor import daa - from hathor.conf import HathorSettings + from hathor.conf.get_settings import get_settings from tests.utils import add_new_blocks, gen_new_tx - settings = HathorSettings() + settings = get_settings() assert manager.wallet is not None address = manager.wallet.get_unused_address(mark_as_used=False) diff --git a/hathor/cli/nginx_config.py b/hathor/cli/nginx_config.py index d441a4842..18a6f4afe 100644 --- a/hathor/cli/nginx_config.py +++ b/hathor/cli/nginx_config.py @@ -115,9 +115,9 @@ def generate_nginx_config(openapi: dict[str, Any], *, out_file: TextIO, rate_k: """ from datetime import datetime - from hathor.conf import HathorSettings + from hathor.conf.get_settings import get_settings - settings = HathorSettings() + settings = get_settings() api_prefix = settings.API_VERSION_PREFIX locations: dict[str, dict[str, Any]] = {} diff --git a/hathor/cli/run_node.py b/hathor/cli/run_node.py index f3198fc26..b39cb0255 100644 --- a/hathor/cli/run_node.py +++ b/hathor/cli/run_node.py @@ -159,8 +159,8 @@ def prepare(self, *, register_resources: bool = True) -> None: assert self.manager.stratum_factory is not None self.reactor.listenTCP(self._args.stratum, self.manager.stratum_factory) - from hathor.conf import HathorSettings - settings = HathorSettings() + from hathor.conf.get_settings import get_settings + settings = get_settings() if register_resources: resources_builder = ResourcesBuilder( @@ -204,8 +204,8 @@ def start_sentry_if_possible(self) -> None: sys.exit(-3) import hathor - from hathor.conf import HathorSettings - settings = HathorSettings() + from hathor.conf.get_settings import get_settings + settings = get_settings() sentry_sdk.init( dsn=self._args.sentry_dsn, release=hathor.__version__, diff --git a/hathor/consensus/block_consensus.py b/hathor/consensus/block_consensus.py index 9ad148de4..18a6da20d 100644 --- a/hathor/consensus/block_consensus.py +++ b/hathor/consensus/block_consensus.py @@ -17,7 +17,7 @@ from structlog import get_logger -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.profiler import get_cpu_profiler from hathor.transaction import BaseTransaction, Block, Transaction, sum_weights from hathor.util import classproperty, not_none @@ -26,7 +26,6 @@ from hathor.consensus.context import ConsensusAlgorithmContext logger = get_logger() -settings = HathorSettings() cpu = get_cpu_profiler() _base_transaction_log = logger.new() @@ -36,6 +35,7 @@ class BlockConsensusAlgorithm: """Implement the consensus algorithm for blocks.""" def __init__(self, context: 'ConsensusAlgorithmContext') -> None: + self._settings = get_settings() self.context = context @classproperty @@ -149,7 +149,7 @@ def update_voided_info(self, block: Block) -> None: storage.indexes.height.add_new(block.get_height(), block.hash, block.timestamp) storage.update_best_block_tips_cache([block.hash]) # The following assert must be true, but it is commented out for performance reasons. - if settings.SLOW_ASSERTS: + if self._settings.SLOW_ASSERTS: assert len(storage.get_best_block_tips(skip_cache=True)) == 1 else: # Resolve all other cases, but (i). @@ -179,7 +179,7 @@ def update_voided_info(self, block: Block) -> None: score = self.calculate_score(block) # Finally, check who the winner is. - if score <= best_score - settings.WEIGHT_TOL: + if score <= best_score - self._settings.WEIGHT_TOL: # Just update voided_by from parents. self.update_voided_by_from_parents(block) @@ -200,7 +200,7 @@ def update_voided_info(self, block: Block) -> None: common_block = self._find_first_parent_in_best_chain(block) self.add_voided_by_to_multiple_chains(block, heads, common_block) - if score >= best_score + settings.WEIGHT_TOL: + if score >= best_score + self._settings.WEIGHT_TOL: # We have a new winner candidate. self.update_score_and_mark_as_the_best_chain_if_possible(block) # As `update_score_and_mark_as_the_best_chain_if_possible` may affect `voided_by`, @@ -294,10 +294,10 @@ def update_score_and_mark_as_the_best_chain_if_possible(self, block: Block) -> N best_heads: list[Block] for head in heads: head_meta = head.get_metadata(force_reload=True) - if head_meta.score <= best_score - settings.WEIGHT_TOL: + if head_meta.score <= best_score - self._settings.WEIGHT_TOL: continue - if head_meta.score >= best_score + settings.WEIGHT_TOL: + if head_meta.score >= best_score + self._settings.WEIGHT_TOL: best_heads = [head] best_score = head_meta.score else: diff --git a/hathor/consensus/consensus.py b/hathor/consensus/consensus.py index acf3c5d6f..6ffe1acba 100644 --- a/hathor/consensus/consensus.py +++ b/hathor/consensus/consensus.py @@ -14,7 +14,7 @@ from structlog import get_logger -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.consensus.block_consensus import BlockConsensusAlgorithmFactory from hathor.consensus.context import ConsensusAlgorithmContext from hathor.consensus.transaction_consensus import TransactionConsensusAlgorithmFactory @@ -24,7 +24,6 @@ from hathor.util import not_none logger = get_logger() -settings = HathorSettings() cpu = get_cpu_profiler() _base_transaction_log = logger.new() @@ -57,6 +56,7 @@ class ConsensusAlgorithm: """ def __init__(self, soft_voided_tx_ids: set[bytes], pubsub: PubSubManager) -> None: + self._settings = get_settings() self.log = logger.new() self._pubsub = pubsub self.soft_voided_tx_ids = frozenset(soft_voided_tx_ids) @@ -76,7 +76,7 @@ def update(self, base: BaseTransaction) -> None: try: self._unsafe_update(base) except Exception: - meta.add_voided_by(settings.CONSENSUS_FAIL_ID) + meta.add_voided_by(self._settings.CONSENSUS_FAIL_ID) assert base.storage is not None base.storage.save_transaction(base, only_metadata=True) raise @@ -87,7 +87,7 @@ def _unsafe_update(self, base: BaseTransaction) -> None: # XXX: first make sure we can run the consensus update on this tx: meta = base.get_metadata() - assert meta.voided_by is None or (settings.PARTIALLY_VALIDATED_ID not in meta.voided_by) + assert meta.voided_by is None or (self._settings.PARTIALLY_VALIDATED_ID not in meta.voided_by) assert meta.validation.is_fully_connected() # this context instance will live only while this update is running @@ -152,9 +152,9 @@ def filter_out_soft_voided_entries(self, tx: BaseTransaction, voided_by: set[byt return voided_by ret = set() for h in voided_by: - if h == settings.SOFT_VOIDED_ID: + if h == self._settings.SOFT_VOIDED_ID: continue - if h == settings.CONSENSUS_FAIL_ID: + if h == self._settings.CONSENSUS_FAIL_ID: continue if h == tx.hash: continue diff --git a/hathor/consensus/context.py b/hathor/consensus/context.py index 0e74737ae..5896ed553 100644 --- a/hathor/consensus/context.py +++ b/hathor/consensus/context.py @@ -16,7 +16,6 @@ from structlog import get_logger -from hathor.conf import HathorSettings from hathor.profiler import get_cpu_profiler from hathor.pubsub import PubSubManager from hathor.transaction import BaseTransaction, Block @@ -27,7 +26,6 @@ from hathor.consensus.transaction_consensus import TransactionConsensusAlgorithm logger = get_logger() -settings = HathorSettings() cpu = get_cpu_profiler() _base_transaction_log = logger.new() diff --git a/hathor/consensus/transaction_consensus.py b/hathor/consensus/transaction_consensus.py index 78c4454d9..0747c1753 100644 --- a/hathor/consensus/transaction_consensus.py +++ b/hathor/consensus/transaction_consensus.py @@ -16,7 +16,7 @@ from structlog import get_logger -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.profiler import get_cpu_profiler from hathor.transaction import BaseTransaction, Block, Transaction, TxInput, sum_weights from hathor.util import classproperty @@ -25,7 +25,6 @@ from hathor.consensus.context import ConsensusAlgorithmContext logger = get_logger() -settings = HathorSettings() cpu = get_cpu_profiler() _base_transaction_log = logger.new() @@ -35,6 +34,7 @@ class TransactionConsensusAlgorithm: """Implement the consensus algorithm for transactions.""" def __init__(self, context: 'ConsensusAlgorithmContext') -> None: + self._settings = get_settings() self.context = context @classproperty @@ -180,7 +180,7 @@ def update_voided_info(self, tx: Transaction) -> None: parent_meta = parent.get_metadata() if parent_meta.voided_by: voided_by.update(self.context.consensus.filter_out_soft_voided_entries(parent, parent_meta.voided_by)) - assert settings.SOFT_VOIDED_ID not in voided_by + assert self._settings.SOFT_VOIDED_ID not in voided_by assert not (self.context.consensus.soft_voided_tx_ids & voided_by) # Union of voided_by of inputs @@ -189,13 +189,13 @@ def update_voided_info(self, tx: Transaction) -> None: spent_meta = spent_tx.get_metadata() if spent_meta.voided_by: voided_by.update(spent_meta.voided_by) - voided_by.discard(settings.SOFT_VOIDED_ID) - assert settings.SOFT_VOIDED_ID not in voided_by + voided_by.discard(self._settings.SOFT_VOIDED_ID) + assert self._settings.SOFT_VOIDED_ID not in voided_by # Update accumulated weight of the transactions voiding us. assert tx.hash not in voided_by for h in voided_by: - if h == settings.SOFT_VOIDED_ID: + if h == self._settings.SOFT_VOIDED_ID: continue tx2 = tx.storage.get_transaction(h) tx2_meta = tx2.get_metadata() @@ -207,7 +207,7 @@ def update_voided_info(self, tx: Transaction) -> None: assert not meta.voided_by or meta.voided_by == {tx.hash} assert meta.accumulated_weight == tx.weight if tx.hash in self.context.consensus.soft_voided_tx_ids: - voided_by.add(settings.SOFT_VOIDED_ID) + voided_by.add(self._settings.SOFT_VOIDED_ID) voided_by.add(tx.hash) if meta.conflict_with: voided_by.add(tx.hash) @@ -221,7 +221,7 @@ def update_voided_info(self, tx: Transaction) -> None: # Check conflicts of the transactions voiding us. for h in voided_by: - if h == settings.SOFT_VOIDED_ID: + if h == self._settings.SOFT_VOIDED_ID: continue if h == tx.hash: continue @@ -300,7 +300,7 @@ def check_conflicts(self, tx: Transaction) -> None: candidate.update_accumulated_weight(stop_value=meta.accumulated_weight) tx_meta = candidate.get_metadata() d = tx_meta.accumulated_weight - meta.accumulated_weight - if abs(d) < settings.WEIGHT_TOL: + if abs(d) < self._settings.WEIGHT_TOL: tie_list.append(candidate) elif d > 0: is_highest = False diff --git a/hathor/crypto/util.py b/hathor/crypto/util.py index 128ec0be1..9bf4bad89 100644 --- a/hathor/crypto/util.py +++ b/hathor/crypto/util.py @@ -27,11 +27,9 @@ load_der_private_key, ) -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.util import not_none -settings = HathorSettings() - _BACKEND = default_backend() @@ -119,8 +117,7 @@ def get_address_b58_from_public_key_hash(public_key_hash: bytes) -> str: return base58.b58encode(address).decode('utf-8') -def get_address_from_public_key_hash(public_key_hash: bytes, - version_byte: bytes = settings.P2PKH_VERSION_BYTE) -> bytes: +def get_address_from_public_key_hash(public_key_hash: bytes, version_byte: Optional[bytes] = None) -> bytes: """Gets the address in bytes from the public key hash :param public_key_hash: hash of public key (sha256 and ripemd160) @@ -132,9 +129,11 @@ def get_address_from_public_key_hash(public_key_hash: bytes, :return: address in bytes :rtype: bytes """ + settings = get_settings() address = b'' + actual_version_byte: bytes = version_byte if version_byte is not None else settings.P2PKH_VERSION_BYTE # Version byte - address += version_byte + address += actual_version_byte # Pubkey hash address += public_key_hash checksum = get_checksum(address) @@ -200,8 +199,7 @@ def get_public_key_from_bytes_compressed(public_key_bytes: bytes) -> ec.Elliptic return ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256K1(), public_key_bytes) -def get_address_b58_from_redeem_script_hash(redeem_script_hash: bytes, - version_byte: bytes = settings.MULTISIG_VERSION_BYTE) -> str: +def get_address_b58_from_redeem_script_hash(redeem_script_hash: bytes, version_byte: Optional[bytes] = None) -> str: """Gets the b58 address from the hash of the redeem script in multisig. :param redeem_script_hash: hash of the redeem script (sha256 and ripemd160) @@ -210,12 +208,13 @@ def get_address_b58_from_redeem_script_hash(redeem_script_hash: bytes, :return: address in base 58 :rtype: string """ - address = get_address_from_redeem_script_hash(redeem_script_hash, version_byte) + settings = get_settings() + actual_version_byte: bytes = version_byte if version_byte is not None else settings.MULTISIG_VERSION_BYTE + address = get_address_from_redeem_script_hash(redeem_script_hash, actual_version_byte) return base58.b58encode(address).decode('utf-8') -def get_address_from_redeem_script_hash(redeem_script_hash: bytes, - version_byte: bytes = settings.MULTISIG_VERSION_BYTE) -> bytes: +def get_address_from_redeem_script_hash(redeem_script_hash: bytes, version_byte: Optional[bytes] = None) -> bytes: """Gets the address in bytes from the redeem script hash :param redeem_script_hash: hash of redeem script (sha256 and ripemd160) @@ -227,9 +226,11 @@ def get_address_from_redeem_script_hash(redeem_script_hash: bytes, :return: address in bytes :rtype: bytes """ + settings = get_settings() + actual_version_byte: bytes = version_byte if version_byte is not None else settings.MULTISIG_VERSION_BYTE address = b'' # Version byte - address += version_byte + address += actual_version_byte # redeem script hash address += redeem_script_hash checksum = get_checksum(address) diff --git a/hathor/graphviz.py b/hathor/graphviz.py index f0abe04fe..3e06bed8b 100644 --- a/hathor/graphviz.py +++ b/hathor/graphviz.py @@ -18,16 +18,15 @@ from graphviz import Digraph -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.transaction import BaseTransaction from hathor.transaction.storage import TransactionStorage -settings = HathorSettings() - class GraphvizVisualizer: def __init__(self, storage: TransactionStorage, include_funds: bool = False, include_verifications: bool = False, only_blocks: bool = False): + self._settings = get_settings() self.storage = storage # Indicate whether it should show fund edges @@ -92,7 +91,7 @@ def get_node_attrs(self, tx: BaseTransaction) -> dict[str, str]: if meta.voided_by and len(meta.voided_by) > 0: if meta.voided_by and tx.hash in meta.voided_by: node_attrs.update(self.conflict_attrs) - if settings.SOFT_VOIDED_ID in meta.voided_by: + if self._settings.SOFT_VOIDED_ID in meta.voided_by: node_attrs.update(self.soft_voided_attrs) else: node_attrs.update(self.voided_attrs) diff --git a/hathor/indexes/rocksdb_height_index.py b/hathor/indexes/rocksdb_height_index.py index 72964f754..512606de8 100644 --- a/hathor/indexes/rocksdb_height_index.py +++ b/hathor/indexes/rocksdb_height_index.py @@ -16,14 +16,12 @@ from structlog import get_logger -from hathor.conf import HathorSettings from hathor.indexes.height_index import BLOCK_GENESIS_ENTRY, HeightIndex, HeightInfo, IndexEntry from hathor.indexes.rocksdb_utils import RocksDBIndexUtils if TYPE_CHECKING: # pragma: no cover import rocksdb -settings = HathorSettings() logger = get_logger() _CF_NAME_HEIGHT_INDEX = b'height-index' diff --git a/hathor/indexes/rocksdb_tokens_index.py b/hathor/indexes/rocksdb_tokens_index.py index 2f001610d..575b44f37 100644 --- a/hathor/indexes/rocksdb_tokens_index.py +++ b/hathor/indexes/rocksdb_tokens_index.py @@ -18,7 +18,7 @@ from structlog import get_logger -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.indexes.rocksdb_utils import ( InternalUid, RocksDBIndexUtils, @@ -34,7 +34,6 @@ if TYPE_CHECKING: # pragma: no cover import rocksdb -settings = HathorSettings() logger = get_logger() _CF_NAME_TOKENS_INDEX = b'tokens-index' @@ -86,6 +85,7 @@ class RocksDBTokensIndex(TokensIndex, RocksDBIndexUtils): """ def __init__(self, db: 'rocksdb.DB', *, cf_name: Optional[bytes] = None) -> None: + self._settings = get_settings() self.log = logger.new() RocksDBIndexUtils.__init__(self, db, cf_name or _CF_NAME_TOKENS_INDEX) @@ -219,16 +219,16 @@ def _remove_authority_utxo(self, token_uid: bytes, tx_hash: bytes, index: int, * def _create_genesis_info(self) -> None: self._create_token_info( - settings.HATHOR_TOKEN_UID, - settings.HATHOR_TOKEN_NAME, - settings.HATHOR_TOKEN_SYMBOL, - settings.GENESIS_TOKENS, + self._settings.HATHOR_TOKEN_UID, + self._settings.HATHOR_TOKEN_NAME, + self._settings.HATHOR_TOKEN_SYMBOL, + self._settings.GENESIS_TOKENS, ) def _add_to_total(self, token_uid: bytes, amount: int) -> None: key_info = self._to_key_info(token_uid) old_value_info = self._db.get((self._cf, key_info)) - if token_uid == settings.HATHOR_TOKEN_UID and old_value_info is None: + if token_uid == self._settings.HATHOR_TOKEN_UID and old_value_info is None: self._create_genesis_info() old_value_info = self._db.get((self._cf, key_info)) assert old_value_info is not None @@ -240,7 +240,7 @@ def _add_to_total(self, token_uid: bytes, amount: int) -> None: def _subtract_from_total(self, token_uid: bytes, amount: int) -> None: key_info = self._to_key_info(token_uid) old_value_info = self._db.get((self._cf, key_info)) - if token_uid == settings.HATHOR_TOKEN_UID and old_value_info is None: + if token_uid == self._settings.HATHOR_TOKEN_UID and old_value_info is None: self._create_genesis_info() old_value_info = self._db.get((self._cf, key_info)) assert old_value_info is not None diff --git a/hathor/indexes/rocksdb_utils.py b/hathor/indexes/rocksdb_utils.py index 87fddcb54..8ce19ba39 100644 --- a/hathor/indexes/rocksdb_utils.py +++ b/hathor/indexes/rocksdb_utils.py @@ -15,15 +15,13 @@ from collections.abc import Collection from typing import TYPE_CHECKING, Iterable, Iterator, NewType -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings if TYPE_CHECKING: # pragma: no cover import rocksdb import structlog -settings = HathorSettings() - # the following type is used to help a little bit to distinguish when we're using a byte sequence that should only be # internally used InternalUid = NewType('InternalUid', bytes) @@ -32,6 +30,7 @@ def to_internal_token_uid(token_uid: bytes) -> InternalUid: """Normalizes a token_uid so that the native token (\x00) will have the same length as custom tokens.""" + settings = get_settings() if token_uid == settings.HATHOR_TOKEN_UID: return _INTERNAL_HATHOR_TOKEN_UID assert len(token_uid) == 32 @@ -41,6 +40,7 @@ def to_internal_token_uid(token_uid: bytes) -> InternalUid: def from_internal_token_uid(token_uid: InternalUid) -> bytes: """De-normalizes the token_uid so that the native token is b'\x00' as expected""" assert len(token_uid) == 32 + settings = get_settings() if token_uid == _INTERNAL_HATHOR_TOKEN_UID: return settings.HATHOR_TOKEN_UID return token_uid diff --git a/hathor/indexes/utxo_index.py b/hathor/indexes/utxo_index.py index f99a62c51..5b1cf34ee 100644 --- a/hathor/indexes/utxo_index.py +++ b/hathor/indexes/utxo_index.py @@ -18,7 +18,7 @@ from structlog import get_logger -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.indexes.base_index import BaseIndex from hathor.indexes.scope import Scope from hathor.transaction import BaseTransaction, Block, TxOutput @@ -26,7 +26,6 @@ from hathor.util import sorted_merger logger = get_logger() -settings = HathorSettings() SCOPE = Scope( include_blocks=True, @@ -61,6 +60,7 @@ def __repr__(self): @classmethod def from_tx_output(cls, tx: BaseTransaction, index: int, tx_output: TxOutput) -> 'UtxoIndexItem': assert tx.hash is not None + settings = get_settings() if tx_output.is_token_authority(): raise ValueError('UtxoIndexItem cannot be used with a token authority output') @@ -206,6 +206,7 @@ def iter_utxos(self, *, address: str, target_amount: int, token_uid: Optional[by target_height: Optional[int] = None) -> Iterator[UtxoIndexItem]: """ Search UTXOs for a given token_uid+address+target_value, if no token_uid is given, HTR is assumed. """ + settings = get_settings() actual_token_uid = token_uid if token_uid is not None else settings.HATHOR_TOKEN_UID iter_nolock = self._iter_utxos_nolock(token_uid=actual_token_uid, address=address, target_amount=target_amount) diff --git a/hathor/merged_mining/coordinator.py b/hathor/merged_mining/coordinator.py index 0c32cf985..61c9c2a65 100644 --- a/hathor/merged_mining/coordinator.py +++ b/hathor/merged_mining/coordinator.py @@ -28,7 +28,6 @@ from structlog import get_logger from hathor.client import IHathorClient, IMiningChannel -from hathor.conf import HathorSettings from hathor.crypto.util import decode_address from hathor.difficulty import Hash, PDiff, Target, Weight from hathor.merged_mining.bitcoin import ( @@ -51,7 +50,6 @@ from hathor.util import MaxSizeOrderedDict, Random, ichunks logger = get_logger() -settings = HathorSettings() MAGIC_NUMBER = b'Hath' # bytes.fromhex('48617468') or 0x68746148.to_bytes(4, 'little') diff --git a/hathor/mining/ws.py b/hathor/mining/ws.py index acd040ace..e4839f525 100644 --- a/hathor/mining/ws.py +++ b/hathor/mining/ws.py @@ -22,14 +22,12 @@ from autobahn.twisted.websocket import WebSocketServerFactory, WebSocketServerProtocol from structlog import get_logger -from hathor.conf import HathorSettings from hathor.manager import HathorManager from hathor.pubsub import EventArguments, HathorEvents from hathor.transaction.base_transaction import tx_or_block_from_bytes from hathor.util import json_dumpb, json_loadb logger = get_logger() -settings = HathorSettings() JsonRpcId = Union[str, int, float] JsonValue = Optional[Union[dict[str, Any], list[Any], str, int, float]] diff --git a/hathor/p2p/peer_id.py b/hathor/p2p/peer_id.py index ad313dde1..612459e7a 100644 --- a/hathor/p2p/peer_id.py +++ b/hathor/p2p/peer_id.py @@ -28,14 +28,12 @@ from twisted.internet.ssl import Certificate, CertificateOptions, TLSVersion, trustRootFromCertificates from hathor import daa -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.p2p.utils import connection_string_to_host, discover_dns, generate_certificate if TYPE_CHECKING: from hathor.p2p.protocol import HathorProtocol # noqa: F401 -settings = HathorSettings() - class InvalidPeerIdException(Exception): pass @@ -66,6 +64,7 @@ class PeerId: flags: set[str] def __init__(self, auto_generate_keys: bool = True) -> None: + self._settings = get_settings() self.id = None self.private_key = None self.public_key = None @@ -255,9 +254,9 @@ def increment_retry_attempt(self, now: int) -> None: """ self.retry_timestamp = now + self.retry_interval self.retry_attempts += 1 - self.retry_interval = self.retry_interval * settings.PEER_CONNECTION_RETRY_INTERVAL_MULTIPLIER - if self.retry_interval > settings.PEER_CONNECTION_RETRY_MAX_RETRY_INTERVAL: - self.retry_interval = settings.PEER_CONNECTION_RETRY_MAX_RETRY_INTERVAL + self.retry_interval = self.retry_interval * self._settings.PEER_CONNECTION_RETRY_INTERVAL_MULTIPLIER + if self.retry_interval > self._settings.PEER_CONNECTION_RETRY_MAX_RETRY_INTERVAL: + self.retry_interval = self._settings.PEER_CONNECTION_RETRY_MAX_RETRY_INTERVAL def reset_retry_timestamp(self) -> None: """ Resets retry values. @@ -279,7 +278,11 @@ def can_retry(self, now: int) -> bool: def get_certificate(self) -> x509.Certificate: if not self.certificate: assert self.private_key is not None - certificate = generate_certificate(self.private_key, settings.CA_FILEPATH, settings.CA_KEY_FILEPATH) + certificate = generate_certificate( + self.private_key, + self._settings.CA_FILEPATH, + self._settings.CA_KEY_FILEPATH + ) self.certificate = certificate return self.certificate @@ -300,7 +303,7 @@ def _get_certificate_options(self) -> CertificateOptions: assert self.private_key is not None openssl_pkey = PKey.from_cryptography_key(self.private_key) - with open(settings.CA_FILEPATH, 'rb') as f: + with open(self._settings.CA_FILEPATH, 'rb') as f: ca = x509.load_pem_x509_certificate(data=f.read(), backend=default_backend()) openssl_ca = X509.from_cryptography(ca) diff --git a/hathor/p2p/protocol.py b/hathor/p2p/protocol.py index f2d729c87..822973bed 100644 --- a/hathor/p2p/protocol.py +++ b/hathor/p2p/protocol.py @@ -23,7 +23,7 @@ from twisted.protocols.basic import LineReceiver from twisted.python.failure import Failure -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.p2p.messages import ProtocolMessages from hathor.p2p.peer_id import PeerId from hathor.p2p.rate_limiter import RateLimiter @@ -36,7 +36,6 @@ from hathor.manager import HathorManager # noqa: F401 from hathor.p2p.manager import ConnectionsManager # noqa: F401 -settings = HathorSettings() logger = get_logger() cpu = get_cpu_profiler() @@ -94,6 +93,7 @@ class WarningFlags(str, Enum): def __init__(self, network: str, my_peer: PeerId, p2p_manager: 'ConnectionsManager', *, use_ssl: bool, inbound: bool) -> None: + self._settings = get_settings() self.network = network self.my_peer = my_peer self.connections = p2p_manager @@ -108,7 +108,7 @@ def __init__(self, network: str, my_peer: PeerId, p2p_manager: 'ConnectionsManag self.inbound = inbound # Maximum period without receiving any messages. - self.idle_timeout = settings.PEER_IDLE_TIMEOUT + self.idle_timeout = self._settings.PEER_IDLE_TIMEOUT self._idle_timeout_call_later: Optional[IDelayedCall] = None self._state_instances = {} From 3794dd51dc3d67ed38512e4e8840675bf1bd959a Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Wed, 20 Sep 2023 11:52:44 -0300 Subject: [PATCH 08/26] refactor: move get settings [part 3] (#770) --- hathor/cli/run_node.py | 4 ++-- hathor/p2p/resources/mining_info.py | 7 +++---- hathor/p2p/resources/status.py | 7 +++---- hathor/p2p/states/hello.py | 10 ++++----- hathor/p2p/states/ready.py | 18 ++++++++-------- hathor/transaction/resources/dashboard.py | 9 ++++---- hathor/transaction/resources/mempool.py | 7 +++---- hathor/transaction/resources/push_tx.py | 6 +++--- hathor/transaction/resources/transaction.py | 6 +++--- hathor/transaction/resources/utxo_search.py | 8 +++---- hathor/transaction/scripts.py | 9 +++++--- .../storage/transaction_storage.py | 8 +++---- hathor/transaction/storage/tx_allow_scope.py | 4 ---- hathor/transaction/util.py | 6 +++--- hathor/util.py | 6 +++--- hathor/version_resource.py | 21 +++++++++---------- hathor/wallet/resources/balance.py | 7 +++---- .../resources/thin_wallet/address_balance.py | 11 +++++----- .../resources/thin_wallet/address_history.py | 9 ++++---- .../resources/thin_wallet/address_search.py | 7 +++---- .../resources/thin_wallet/send_tokens.py | 10 ++++----- .../resources/thin_wallet/token_history.py | 7 +++---- hathor/wallet/resources/thin_wallet/tokens.py | 7 +++---- hathor/wallet/util.py | 11 +++++----- 24 files changed, 96 insertions(+), 109 deletions(-) diff --git a/hathor/cli/run_node.py b/hathor/cli/run_node.py index b39cb0255..eb16f5bd1 100644 --- a/hathor/cli/run_node.py +++ b/hathor/cli/run_node.py @@ -266,8 +266,8 @@ def check_unsafe_arguments(self) -> None: '', ] - from hathor.conf import HathorSettings - settings = HathorSettings() + from hathor.conf.get_settings import get_settings + settings = get_settings() if self._args.unsafe_mode != settings.NETWORK_NAME: message.extend([ diff --git a/hathor/p2p/resources/mining_info.py b/hathor/p2p/resources/mining_info.py index 518317b3f..4aae45616 100644 --- a/hathor/p2p/resources/mining_info.py +++ b/hathor/p2p/resources/mining_info.py @@ -16,13 +16,11 @@ from hathor.api_util import Resource, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.daa import get_mined_tokens from hathor.difficulty import Weight from hathor.util import json_dumpb -settings = HathorSettings() - @register_resource class MiningInfoResource(Resource): @@ -33,6 +31,7 @@ class MiningInfoResource(Resource): isLeaf = True def __init__(self, manager): + self._settings = get_settings() self.manager = manager def render_GET(self, request): @@ -48,7 +47,7 @@ def render_GET(self, request): # We can use any address. burn_address = bytes.fromhex( - settings.P2PKH_VERSION_BYTE.hex() + 'acbfb94571417423c1ed66f706730c4aea516ac5762cccb8' + self._settings.P2PKH_VERSION_BYTE.hex() + 'acbfb94571417423c1ed66f706730c4aea516ac5762cccb8' ) block = self.manager.generate_mining_block(address=burn_address) diff --git a/hathor/p2p/resources/status.py b/hathor/p2p/resources/status.py index 7287c6c1a..0d1434771 100644 --- a/hathor/p2p/resources/status.py +++ b/hathor/p2p/resources/status.py @@ -17,12 +17,10 @@ import hathor from hathor.api_util import Resource, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.p2p.utils import to_serializable_best_blockchain from hathor.util import json_dumpb -settings = HathorSettings() - @register_resource class StatusResource(Resource): @@ -34,6 +32,7 @@ class StatusResource(Resource): isLeaf = True def __init__(self, manager): + self._settings = get_settings() self.manager = manager def render_GET(self, request): @@ -94,7 +93,7 @@ def render_GET(self, request): best_block_tips.append({'hash': tx.hash_hex, 'height': meta.height}) best_block = self.manager.tx_storage.get_best_block() - raw_best_blockchain = self.manager.tx_storage.get_n_height_tips(settings.DEFAULT_BEST_BLOCKCHAIN_BLOCKS) + raw_best_blockchain = self.manager.tx_storage.get_n_height_tips(self._settings.DEFAULT_BEST_BLOCKCHAIN_BLOCKS) best_blockchain = to_serializable_best_blockchain(raw_best_blockchain) data = { diff --git a/hathor/p2p/states/hello.py b/hathor/p2p/states/hello.py index ee42c5e4f..d731e2bfa 100644 --- a/hathor/p2p/states/hello.py +++ b/hathor/p2p/states/hello.py @@ -17,7 +17,7 @@ from structlog import get_logger import hathor -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.exception import HathorError from hathor.p2p.messages import ProtocolMessages from hathor.p2p.states.base import BaseState @@ -30,12 +30,11 @@ logger = get_logger() -settings = HathorSettings() - class HelloState(BaseState): def __init__(self, protocol: 'HathorProtocol') -> None: super().__init__(protocol) + self._settings = get_settings() self.log = logger.new(**protocol.get_logger_context()) self.cmd_map.update({ ProtocolMessages.HELLO: self.handle_hello, @@ -103,7 +102,7 @@ def handle_hello(self, payload: str) -> None: protocol.send_error_and_close_connection('Invalid payload.') return - if settings.ENABLE_PEER_WHITELIST and settings.CAPABILITY_WHITELIST not in data['capabilities']: + if self._settings.ENABLE_PEER_WHITELIST and self._settings.CAPABILITY_WHITELIST not in data['capabilities']: # If peer is not sending whitelist capability we must close the connection protocol.send_error_and_close_connection('Must have whitelist capability.') return @@ -142,7 +141,7 @@ def handle_hello(self, payload: str) -> None: return dt = data['timestamp'] - protocol.node.reactor.seconds() - if abs(dt) > settings.MAX_FUTURE_TIMESTAMP_ALLOWED / 2: + if abs(dt) > self._settings.MAX_FUTURE_TIMESTAMP_ALLOWED / 2: protocol.send_error_and_close_connection('Nodes timestamps too far apart.') return @@ -173,6 +172,7 @@ def handle_hello(self, payload: str) -> None: def _parse_sync_versions(hello_data: dict[str, Any]) -> set[SyncVersion]: """Versions that are not recognized will not be included.""" + settings = get_settings() if settings.CAPABILITY_SYNC_VERSION in hello_data['capabilities']: if 'sync_versions' not in hello_data: raise HathorError('protocol error, expected sync_versions field') diff --git a/hathor/p2p/states/ready.py b/hathor/p2p/states/ready.py index 19d5bddc0..91e58a563 100644 --- a/hathor/p2p/states/ready.py +++ b/hathor/p2p/states/ready.py @@ -18,7 +18,7 @@ from structlog import get_logger from twisted.internet.task import LoopingCall -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.indexes.height_index import HeightInfo from hathor.p2p.messages import ProtocolMessages from hathor.p2p.peer_id import PeerId @@ -33,12 +33,11 @@ logger = get_logger() -settings = HathorSettings() - class ReadyState(BaseState): def __init__(self, protocol: 'HathorProtocol') -> None: super().__init__(protocol) + self._settings = get_settings() self.log = logger.new(**self.protocol.get_logger_context()) @@ -79,7 +78,7 @@ def __init__(self, protocol: 'HathorProtocol') -> None: # if the peer has the GET-BEST-BLOCKCHAIN capability common_capabilities = protocol.capabilities & set(protocol.node.capabilities) - if (settings.CAPABILITY_GET_BEST_BLOCKCHAIN in common_capabilities): + if (self._settings.CAPABILITY_GET_BEST_BLOCKCHAIN in common_capabilities): # set the loop to get the best blockchain from the peer self.lc_get_best_blockchain = LoopingCall(self.send_get_best_blockchain) self.lc_get_best_blockchain.clock = self.reactor @@ -110,7 +109,7 @@ def on_enter(self) -> None: self.send_get_peers() if self.lc_get_best_blockchain is not None: - self.lc_get_best_blockchain.start(settings.BEST_BLOCKCHAIN_INTERVAL, now=False) + self.lc_get_best_blockchain.start(self._settings.BEST_BLOCKCHAIN_INTERVAL, now=False) self.sync_agent.start() @@ -209,11 +208,12 @@ def handle_pong(self, payload: str) -> None: self.ping_start_time = None self.log.debug('rtt updated', rtt=self.ping_rtt, min_rtt=self.ping_min_rtt) - def send_get_best_blockchain(self, n_blocks: int = settings.DEFAULT_BEST_BLOCKCHAIN_BLOCKS) -> None: + def send_get_best_blockchain(self, n_blocks: Optional[int] = None) -> None: """ Send a GET-BEST-BLOCKCHAIN command, requesting a list of the latest N blocks from the best blockchain. """ - self.send_message(ProtocolMessages.GET_BEST_BLOCKCHAIN, str(n_blocks)) + actual_n_blocks: int = n_blocks if n_blocks is not None else self._settings.DEFAULT_BEST_BLOCKCHAIN_BLOCKS + self.send_message(ProtocolMessages.GET_BEST_BLOCKCHAIN, str(actual_n_blocks)) def handle_get_best_blockchain(self, payload: str) -> None: """ Executed when a GET-BEST-BLOCKCHAIN command is received. @@ -228,9 +228,9 @@ def handle_get_best_blockchain(self, payload: str) -> None: ) return - if not (0 < n_blocks <= settings.MAX_BEST_BLOCKCHAIN_BLOCKS): + if not (0 < n_blocks <= self._settings.MAX_BEST_BLOCKCHAIN_BLOCKS): self.protocol.send_error_and_close_connection( - f'N out of bounds. Valid range: [1, {settings.MAX_BEST_BLOCKCHAIN_BLOCKS}].' + f'N out of bounds. Valid range: [1, {self._settings.MAX_BEST_BLOCKCHAIN_BLOCKS}].' ) return diff --git a/hathor/transaction/resources/dashboard.py b/hathor/transaction/resources/dashboard.py index 7b1681d11..c181e210a 100644 --- a/hathor/transaction/resources/dashboard.py +++ b/hathor/transaction/resources/dashboard.py @@ -14,11 +14,9 @@ from hathor.api_util import Resource, get_args, get_missing_params_msg, parse_args, parse_int, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.util import json_dumpb -settings = HathorSettings() - ARGS = ['block', 'tx'] @@ -33,6 +31,7 @@ class DashboardTransactionResource(Resource): def __init__(self, manager): # Important to have the manager so we can know the tx_storage + self._settings = get_settings() self.manager = manager def render_GET(self, request): @@ -69,8 +68,8 @@ def render_GET(self, request): }) # Restrict counts - block_count = min(block_count, settings.MAX_DASHBOARD_COUNT) - tx_count = min(tx_count, settings.MAX_DASHBOARD_COUNT) + block_count = min(block_count, self._settings.MAX_DASHBOARD_COUNT) + tx_count = min(tx_count, self._settings.MAX_DASHBOARD_COUNT) transactions, _ = self.manager.tx_storage.get_newest_txs(count=tx_count) serialized_tx = [tx.to_json_extended() for tx in transactions] diff --git a/hathor/transaction/resources/mempool.py b/hathor/transaction/resources/mempool.py index 937ddcbb2..08340b074 100644 --- a/hathor/transaction/resources/mempool.py +++ b/hathor/transaction/resources/mempool.py @@ -18,12 +18,10 @@ from hathor.api_util import Resource, get_args, parse_args, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.transaction import Transaction from hathor.util import json_dumpb -settings = HathorSettings() - if TYPE_CHECKING: from twisted.web.http import Request @@ -46,6 +44,7 @@ class MempoolResource(Resource): def __init__(self, manager: 'HathorManager'): # Important to have the manager so we can know the tx_storage + self._settings = get_settings() self.manager = manager def render_GET(self, request: 'Request') -> bytes: @@ -82,7 +81,7 @@ def render_GET(self, request: 'Request') -> bytes: sorted(list(self._get_from_index(index_source)), key=lambda tx: tx.timestamp), ) # Only return up to settings.MEMPOOL_API_TX_LIMIT txs per call (default: 100) - data = {'success': True, 'transactions': list(islice(tx_ids, settings.MEMPOOL_API_TX_LIMIT))} + data = {'success': True, 'transactions': list(islice(tx_ids, self._settings.MEMPOOL_API_TX_LIMIT))} return json_dumpb(data) def _get_from_index(self, index_source: IndexSource) -> Iterator[Transaction]: diff --git a/hathor/transaction/resources/push_tx.py b/hathor/transaction/resources/push_tx.py index 6c3dff6c5..0b668274d 100644 --- a/hathor/transaction/resources/push_tx.py +++ b/hathor/transaction/resources/push_tx.py @@ -21,7 +21,7 @@ from hathor.api_util import Resource, get_args, parse_args, render_options, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.exception import InvalidNewTransaction from hathor.transaction import Transaction from hathor.transaction.base_transaction import tx_or_block_from_bytes @@ -31,7 +31,6 @@ if TYPE_CHECKING: from hathor.manager import HathorManager -settings = HathorSettings() logger = get_logger() ARGS = ['hex_tx'] @@ -47,11 +46,12 @@ class PushTxResource(Resource): def __init__(self, manager: 'HathorManager', max_output_script_size: Optional[int] = None, allow_non_standard_script: bool = False) -> None: + self._settings = get_settings() self.log = logger.new() # Important to have the manager so we can know the tx_storage self.manager = manager self.max_output_script_size: int = ( - settings.PUSHTX_MAX_OUTPUT_SCRIPT_SIZE + self._settings.PUSHTX_MAX_OUTPUT_SCRIPT_SIZE if max_output_script_size is None else max_output_script_size ) diff --git a/hathor/transaction/resources/transaction.py b/hathor/transaction/resources/transaction.py index 803e21899..1646e06e5 100644 --- a/hathor/transaction/resources/transaction.py +++ b/hathor/transaction/resources/transaction.py @@ -24,13 +24,11 @@ validate_tx_hash, ) from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.transaction.base_transaction import BaseTransaction, TxVersion from hathor.transaction.token_creation_tx import TokenCreationTransaction from hathor.util import json_dumpb -settings = HathorSettings() - GET_LIST_ARGS = ['count', 'type'] @@ -51,6 +49,7 @@ def get_tx_extra_data(tx: BaseTransaction, *, detail_tokens: bool = True) -> dic assert tx.storage is not None assert tx.storage.indexes is not None + settings = get_settings() serialized = tx.to_json(decode_script=True) serialized['raw'] = tx.get_struct().hex() serialized['nonce'] = str(tx.nonce) @@ -206,6 +205,7 @@ def get_list_tx(self, request): 'timestamp': int, the timestamp reference we are in the pagination 'page': 'previous' or 'next', to indicate if the user wants after or before the hash reference """ + settings = get_settings() raw_args = get_args(request) parsed = parse_args(raw_args, GET_LIST_ARGS) if not parsed['success']: diff --git a/hathor/transaction/resources/utxo_search.py b/hathor/transaction/resources/utxo_search.py index 2f0c4f01f..93f67e561 100644 --- a/hathor/transaction/resources/utxo_search.py +++ b/hathor/transaction/resources/utxo_search.py @@ -24,7 +24,7 @@ set_cors, ) from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.crypto.util import decode_address from hathor.util import json_dumpb from hathor.wallet.exceptions import InvalidAddress @@ -35,9 +35,6 @@ from hathor.manager import HathorManager -settings = HathorSettings() - - @register_resource class UtxoSearchResource(Resource): """ Implements a web server API to return a list of UTXOs that fit a given search criteria. @@ -48,6 +45,7 @@ class UtxoSearchResource(Resource): def __init__(self, manager: 'HathorManager'): # Important to have the manager so we can know the tx_storage + self._settings = get_settings() self.manager = manager def render_GET(self, request: 'Request') -> bytes: @@ -86,7 +84,7 @@ def render_GET(self, request: 'Request') -> bytes: # token_uid parameter must be a valid hash try: token_uid = bytes.fromhex(args['token_uid']) - if token_uid != settings.HATHOR_TOKEN_UID and len(token_uid) != 32: + if token_uid != self._settings.HATHOR_TOKEN_UID and len(token_uid) != 32: raise ValueError('not a valid hash length') except ValueError as e: return json_dumpb({ diff --git a/hathor/transaction/scripts.py b/hathor/transaction/scripts.py index ec2426a79..a3e73cea6 100644 --- a/hathor/transaction/scripts.py +++ b/hathor/transaction/scripts.py @@ -24,7 +24,7 @@ from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.crypto.util import ( decode_address, get_address_b58_from_bytes, @@ -49,8 +49,6 @@ VerifyFailed, ) -settings = HathorSettings() - # XXX: Because the Stack is a heterogeneous list of bytes and int, and some OPs only work for when the stack has some # or the other type, there are many places that require an assert to prevent the wrong type from being used, # alternatives include: 1. only using `list[bytes]` and operations that work on `int` to build them from `bytes`, @@ -691,6 +689,7 @@ def parse_script(cls, script: bytes) -> Optional['NanoContractMatchValues']: def create_base_script(address: str, timelock: Optional[Any] = None) -> BaseScript: """ Verifies if address is P2PKH or Multisig and return the corresponding BaseScript implementation. """ + settings = get_settings() baddress = decode_address(address) if baddress[0] == binary_to_int(settings.P2PKH_VERSION_BYTE): return P2PKH(address, timelock) @@ -713,6 +712,7 @@ def create_output_script(address: bytes, timelock: Optional[Any] = None) -> byte :rtype: bytes """ + settings = get_settings() # XXX: if the address class can somehow be simplified create_base_script could be used here if address[0] == binary_to_int(settings.P2PKH_VERSION_BYTE): return P2PKH.create_output_script(address, timelock) @@ -906,6 +906,7 @@ def count_sigops(data: bytes) -> int: :return: number of signature operations the script would do if it was executed :rtype: int """ + settings = get_settings() n_ops: int = 0 data_len: int = len(data) pos: int = 0 @@ -1534,6 +1535,8 @@ def op_checkmultisig(stack: Stack, log: list[str], extras: ScriptExtras) -> None :raises MissingStackItems: if stack is empty or it has less signatures than the minimum required :raises VerifyFailed: verification failed """ + settings = get_settings() + if not len(stack): raise MissingStackItems('OP_CHECKMULTISIG: empty stack') diff --git a/hathor/transaction/storage/transaction_storage.py b/hathor/transaction/storage/transaction_storage.py index b702838e3..7aa3cffc4 100644 --- a/hathor/transaction/storage/transaction_storage.py +++ b/hathor/transaction/storage/transaction_storage.py @@ -23,7 +23,7 @@ from intervaltree.interval import Interval from structlog import get_logger -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.indexes import IndexesManager from hathor.indexes.height_index import HeightInfo from hathor.profiler import get_cpu_profiler @@ -41,7 +41,6 @@ from hathor.transaction.transaction_metadata import TransactionMetadata from hathor.util import not_none -settings = HathorSettings() cpu = get_cpu_profiler() # these are the timestamp values to be used when resetting them, 1 is used for the node instead of 0, so it can be @@ -87,6 +86,7 @@ class TransactionStorage(ABC): _migrations: list[BaseMigration] def __init__(self) -> None: + self._settings = get_settings() # Weakref is used to guarantee that there is only one instance of each transaction in memory. self._tx_weakref: WeakValueDictionary[bytes, BaseTransaction] = WeakValueDictionary() self._tx_weakref_disabled: bool = False @@ -252,7 +252,7 @@ def _check_and_set_network(self) -> None: """Check the network name is as expected and try to set it when none is present""" from hathor.transaction.storage.exceptions import WrongNetworkError - network = settings.NETWORK_NAME + network = self._settings.NETWORK_NAME stored_network = self.get_network() if stored_network is None: @@ -440,7 +440,7 @@ def post_get_validation(self, tx: BaseTransaction) -> None: def _validate_partial_marker_consistency(self, tx_meta: TransactionMetadata) -> None: voided_by = tx_meta.get_frozen_voided_by() # XXX: PARTIALLY_VALIDATED_ID must be included if the tx is fully connected and must not be included otherwise - has_partially_validated_marker = settings.PARTIALLY_VALIDATED_ID in voided_by + has_partially_validated_marker = self._settings.PARTIALLY_VALIDATED_ID in voided_by validation_is_fully_connected = tx_meta.validation.is_fully_connected() assert (not has_partially_validated_marker) == validation_is_fully_connected, \ 'Inconsistent ValidationState and voided_by' diff --git a/hathor/transaction/storage/tx_allow_scope.py b/hathor/transaction/storage/tx_allow_scope.py index 90f9899e2..47005d68e 100644 --- a/hathor/transaction/storage/tx_allow_scope.py +++ b/hathor/transaction/storage/tx_allow_scope.py @@ -16,16 +16,12 @@ from enum import Flag, auto from typing import TYPE_CHECKING, Generator -from hathor.conf import HathorSettings from hathor.transaction.base_transaction import BaseTransaction if TYPE_CHECKING: from hathor.transaction.storage import TransactionStorage # noqa: F401 -settings = HathorSettings() - - class TxAllowScope(Flag): """ This enum is used internally to mark which "type" of transactions to allow the database to read/write diff --git a/hathor/transaction/util.py b/hathor/transaction/util.py index e58b3d095..d476daeda 100644 --- a/hathor/transaction/util.py +++ b/hathor/transaction/util.py @@ -17,9 +17,7 @@ from math import ceil, floor from typing import Any, Callable, Optional -from hathor.conf import HathorSettings - -settings = HathorSettings() +from hathor.conf.get_settings import get_settings VerboseCallback = Optional[Callable[[str, Any], None]] @@ -51,10 +49,12 @@ def unpack_len(n: int, buf: bytes) -> tuple[bytes, bytes]: def get_deposit_amount(mint_amount: int) -> int: + settings = get_settings() return ceil(abs(settings.TOKEN_DEPOSIT_PERCENTAGE * mint_amount)) def get_withdraw_amount(melt_amount: int) -> int: + settings = get_settings() return floor(abs(settings.TOKEN_DEPOSIT_PERCENTAGE * melt_amount)) diff --git a/hathor/util.py b/hathor/util.py index 73930d41c..3e1b910db 100644 --- a/hathor/util.py +++ b/hathor/util.py @@ -29,7 +29,7 @@ from structlog import get_logger import hathor -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.reactor.reactor import reactor as hathor_reactor from hathor.reactor.reactor_protocol import ReactorProtocol from hathor.types import TokenUid @@ -45,8 +45,6 @@ reactor = hathor_reactor logger = get_logger() -settings = HathorSettings() - T = TypeVar('T') @@ -769,6 +767,7 @@ def is_token_uid_valid(token_uid: TokenUid) -> bool: >>> is_token_uid_valid(bytes.fromhex('000003a3b261e142d3dfd84970d3a50a93b5bc3a66a3b6ba973956148a3eb82400')) False """ + settings = get_settings() if token_uid == settings.HATHOR_TOKEN_UID: return True elif len(token_uid) == 32: @@ -792,6 +791,7 @@ def as_dict(self): def get_environment_info(args: str, peer_id: Optional[str]) -> EnvironmentInfo: + settings = get_settings() environment_info = EnvironmentInfo( python_implementation=str(sys.implementation), hathor_core_args=args, diff --git a/hathor/version_resource.py b/hathor/version_resource.py index 687a20c56..fa7f96ccb 100644 --- a/hathor/version_resource.py +++ b/hathor/version_resource.py @@ -15,11 +15,9 @@ import hathor from hathor.api_util import Resource, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.util import json_dumpb -settings = HathorSettings() - @register_resource class VersionResource(Resource): @@ -31,6 +29,7 @@ class VersionResource(Resource): def __init__(self, manager): # Important to have the manager so we can have access to min_tx_weight_coefficient + self._settings = get_settings() self.manager = manager def render_GET(self, request): @@ -44,14 +43,14 @@ def render_GET(self, request): data = { 'version': hathor.__version__, 'network': self.manager.network, - 'min_weight': settings.MIN_TX_WEIGHT, # DEPRECATED - 'min_tx_weight': settings.MIN_TX_WEIGHT, - 'min_tx_weight_coefficient': settings.MIN_TX_WEIGHT_COEFFICIENT, - 'min_tx_weight_k': settings.MIN_TX_WEIGHT_K, - 'token_deposit_percentage': settings.TOKEN_DEPOSIT_PERCENTAGE, - 'reward_spend_min_blocks': settings.REWARD_SPEND_MIN_BLOCKS, - 'max_number_inputs': settings.MAX_NUM_INPUTS, - 'max_number_outputs': settings.MAX_NUM_OUTPUTS, + 'min_weight': self._settings.MIN_TX_WEIGHT, # DEPRECATED + 'min_tx_weight': self._settings.MIN_TX_WEIGHT, + 'min_tx_weight_coefficient': self._settings.MIN_TX_WEIGHT_COEFFICIENT, + 'min_tx_weight_k': self._settings.MIN_TX_WEIGHT_K, + 'token_deposit_percentage': self._settings.TOKEN_DEPOSIT_PERCENTAGE, + 'reward_spend_min_blocks': self._settings.REWARD_SPEND_MIN_BLOCKS, + 'max_number_inputs': self._settings.MAX_NUM_INPUTS, + 'max_number_outputs': self._settings.MAX_NUM_OUTPUTS, } return json_dumpb(data) diff --git a/hathor/wallet/resources/balance.py b/hathor/wallet/resources/balance.py index 94ef07ef9..43122f5dd 100644 --- a/hathor/wallet/resources/balance.py +++ b/hathor/wallet/resources/balance.py @@ -14,11 +14,9 @@ from hathor.api_util import Resource, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.util import json_dumpb -settings = HathorSettings() - @register_resource class BalanceResource(Resource): @@ -30,6 +28,7 @@ class BalanceResource(Resource): def __init__(self, manager): # Important to have the manager so we can know the tx_storage + self._settings = get_settings() self.manager = manager def render_GET(self, request): @@ -44,7 +43,7 @@ def render_GET(self, request): if not self.manager.wallet: return {'success': False, 'message': 'No wallet started on node'} - data = {'success': True, 'balance': self.manager.wallet.balance[settings.HATHOR_TOKEN_UID]._asdict()} + data = {'success': True, 'balance': self.manager.wallet.balance[self._settings.HATHOR_TOKEN_UID]._asdict()} return json_dumpb(data) diff --git a/hathor/wallet/resources/thin_wallet/address_balance.py b/hathor/wallet/resources/thin_wallet/address_balance.py index 20cecdf3b..a80ec6355 100644 --- a/hathor/wallet/resources/thin_wallet/address_balance.py +++ b/hathor/wallet/resources/thin_wallet/address_balance.py @@ -19,7 +19,7 @@ from hathor.api_util import Resource, get_args, get_missing_params_msg, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.crypto.util import decode_address from hathor.transaction.scripts import parse_address_script from hathor.util import json_dumpb @@ -28,8 +28,6 @@ if TYPE_CHECKING: from hathor.transaction import TxOutput -settings = HathorSettings() - class TokenData: received: int = 0 @@ -55,6 +53,7 @@ class AddressBalanceResource(Resource): isLeaf = True def __init__(self, manager): + self._settings = get_settings() self.manager = manager def has_address(self, output: 'TxOutput', requested_address: str) -> bool: @@ -123,9 +122,9 @@ def render_GET(self, request: Request) -> bytes: return_tokens_data: dict[str, dict[str, Any]] = {} for token_uid in tokens_data.keys(): - if token_uid == settings.HATHOR_TOKEN_UID: - tokens_data[token_uid].name = settings.HATHOR_TOKEN_NAME - tokens_data[token_uid].symbol = settings.HATHOR_TOKEN_SYMBOL + if token_uid == self._settings.HATHOR_TOKEN_UID: + tokens_data[token_uid].name = self._settings.HATHOR_TOKEN_NAME + tokens_data[token_uid].symbol = self._settings.HATHOR_TOKEN_SYMBOL else: try: token_info = tokens_index.get_token_info(token_uid) diff --git a/hathor/wallet/resources/thin_wallet/address_history.py b/hathor/wallet/resources/thin_wallet/address_history.py index b0dc800b8..ef4dc323b 100644 --- a/hathor/wallet/resources/thin_wallet/address_history.py +++ b/hathor/wallet/resources/thin_wallet/address_history.py @@ -19,13 +19,11 @@ from hathor.api_util import Resource, get_args, get_missing_params_msg, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.crypto.util import decode_address from hathor.util import json_dumpb, json_loadb from hathor.wallet.exceptions import InvalidAddress -settings = HathorSettings() - @register_resource class AddressHistoryResource(Resource): @@ -36,6 +34,7 @@ class AddressHistoryResource(Resource): isLeaf = True def __init__(self, manager): + self._settings = get_settings() self.manager = manager # TODO add openapi docs for this API @@ -201,7 +200,7 @@ def get_address_history(self, addresses: list[str], ref_hash: Optional[str]) -> to_iterate = hashes[start_index:] did_break = False for index, tx_hash in enumerate(to_iterate): - if total_added == settings.MAX_TX_ADDRESSES_HISTORY: + if total_added == self._settings.MAX_TX_ADDRESSES_HISTORY: # If already added the max number of elements possible, then break # I need to add this if at the beginning of the loop to handle the case # when the first tx of the address exceeds the limit, so we must return @@ -212,7 +211,7 @@ def get_address_history(self, addresses: list[str], ref_hash: Optional[str]) -> if tx_hash not in seen: tx = self.manager.tx_storage.get_transaction(tx_hash) tx_elements = len(tx.inputs) + len(tx.outputs) - if total_elements + tx_elements > settings.MAX_INPUTS_OUTPUTS_ADDRESS_HISTORY: + if total_elements + tx_elements > self._settings.MAX_INPUTS_OUTPUTS_ADDRESS_HISTORY: # If the adition of this tx overcomes the maximum number of inputs and outputs, then break # It's important to validate also the maximum number of inputs and outputs because some txs # are really big and the response payload becomes too big diff --git a/hathor/wallet/resources/thin_wallet/address_search.py b/hathor/wallet/resources/thin_wallet/address_search.py index 681e4ac59..ef63bc50f 100644 --- a/hathor/wallet/resources/thin_wallet/address_search.py +++ b/hathor/wallet/resources/thin_wallet/address_search.py @@ -18,7 +18,7 @@ from hathor.api_util import Resource, get_args, get_missing_params_msg, parse_int, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.crypto.util import decode_address from hathor.transaction.scripts import parse_address_script from hathor.util import json_dumpb @@ -27,8 +27,6 @@ if TYPE_CHECKING: from hathor.transaction import BaseTransaction -settings = HathorSettings() - @register_resource class AddressSearchResource(Resource): @@ -39,6 +37,7 @@ class AddressSearchResource(Resource): isLeaf = True def __init__(self, manager): + self._settings = get_settings() self.manager = manager def has_token_and_address(self, tx: 'BaseTransaction', address: str, token: bytes) -> bool: @@ -108,7 +107,7 @@ def render_GET(self, request: Request) -> bytes: }) try: - count = parse_int(raw_args[b'count'][0], cap=settings.MAX_TX_COUNT) + count = parse_int(raw_args[b'count'][0], cap=self._settings.MAX_TX_COUNT) except ValueError as e: return json_dumpb({ 'success': False, diff --git a/hathor/wallet/resources/thin_wallet/send_tokens.py b/hathor/wallet/resources/thin_wallet/send_tokens.py index 219ba8912..a932600aa 100644 --- a/hathor/wallet/resources/thin_wallet/send_tokens.py +++ b/hathor/wallet/resources/thin_wallet/send_tokens.py @@ -25,14 +25,13 @@ from hathor.api_util import Resource, render_options, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.exception import InvalidNewTransaction from hathor.transaction import Transaction from hathor.transaction.base_transaction import tx_or_block_from_bytes from hathor.transaction.exceptions import TxValidationError from hathor.util import json_dumpb, json_loadb, reactor -settings = HathorSettings() logger = get_logger() # Timeout for the pow resolution in stratum (in seconds) @@ -56,6 +55,7 @@ class SendTokensResource(Resource): def __init__(self, manager): # Important to have the manager so we can know the tx_storage + self._settings = get_settings() self.manager = manager self.sleep_seconds = 0 self.log = logger.new() @@ -72,7 +72,7 @@ def render_POST(self, request: Request) -> Any: set_cors(request, 'POST') # Validating if we still have unused threads to solve the pow - if len(self.manager.pow_thread_pool.working) == settings.MAX_POW_THREADS: + if len(self.manager.pow_thread_pool.working) == self._settings.MAX_POW_THREADS: return self.return_POST( False, 'The server is currently fully loaded to send tokens. Wait a moment and try again, please.', @@ -133,7 +133,7 @@ def render_POST(self, request: Request) -> Any: context = _Context(tx=tx, request=request) - if settings.SEND_TOKENS_STRATUM and self.manager.stratum_factory: + if self._settings.SEND_TOKENS_STRATUM and self.manager.stratum_factory: self._render_POST_stratum(context) else: self._render_POST(context) @@ -186,7 +186,7 @@ def _responseFailed(self, err, context): # response failed, should stop mining tx = context.tx self.log.warn('connection closed while resolving transaction proof of work', tx=tx) - if settings.SEND_TOKENS_STRATUM and self.manager.stratum_factory: + if self._settings.SEND_TOKENS_STRATUM and self.manager.stratum_factory: funds_hash = tx.get_funds_hash() self._cleanup_stratum(funds_hash) # start new job in stratum, so the miner doesn't waste more time on this tx diff --git a/hathor/wallet/resources/thin_wallet/token_history.py b/hathor/wallet/resources/thin_wallet/token_history.py index 8f1f7681f..698aa94cd 100644 --- a/hathor/wallet/resources/thin_wallet/token_history.py +++ b/hathor/wallet/resources/thin_wallet/token_history.py @@ -16,11 +16,9 @@ from hathor.api_util import Resource, get_args, get_missing_params_msg, parse_args, parse_int, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.util import json_dumpb -settings = HathorSettings() - ARGS = ['id', 'count'] @@ -33,6 +31,7 @@ class TokenHistoryResource(Resource): isLeaf = True def __init__(self, manager): + self._settings = get_settings() self.manager = manager def render_GET(self, request: Request) -> bytes: @@ -69,7 +68,7 @@ def render_GET(self, request: Request) -> bytes: return json_dumpb({'success': False, 'message': 'Invalid token id'}) try: - count = parse_int(parsed['args']['count'], cap=settings.MAX_TX_COUNT) + count = parse_int(parsed['args']['count'], cap=self._settings.MAX_TX_COUNT) except ValueError as e: return json_dumpb({ 'success': False, diff --git a/hathor/wallet/resources/thin_wallet/tokens.py b/hathor/wallet/resources/thin_wallet/tokens.py index 6e2789f01..3190aaa5b 100644 --- a/hathor/wallet/resources/thin_wallet/tokens.py +++ b/hathor/wallet/resources/thin_wallet/tokens.py @@ -18,11 +18,9 @@ from hathor.api_util import Resource, get_args, set_cors from hathor.cli.openapi_files.register import register_resource -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.util import is_token_uid_valid, json_dumpb -settings = HathorSettings() - @register_resource class TokenResource(Resource): @@ -33,6 +31,7 @@ class TokenResource(Resource): isLeaf = True def __init__(self, manager): + self._settings = get_settings() self.manager = manager def get_one_token_data(self, token_uid: bytes) -> dict[str, Any]: @@ -85,7 +84,7 @@ def get_list_token_data(self) -> dict[str, Any]: limit = 200 truncated = False for uid, token_info in all_tokens: - if uid == settings.HATHOR_TOKEN_UID: + if uid == self._settings.HATHOR_TOKEN_UID: continue if count >= limit: diff --git a/hathor/wallet/util.py b/hathor/wallet/util.py index d8c1fa3a7..111f07ac0 100644 --- a/hathor/wallet/util.py +++ b/hathor/wallet/util.py @@ -19,13 +19,11 @@ from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec -from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.crypto.util import get_hash160, get_private_key_from_bytes from hathor.transaction.scripts import HathorScript, Opcode from hathor.transaction.transaction import Transaction -settings = HathorSettings() - def generate_multisig_redeem_script(signatures_required: int, public_key_bytes: list[bytes]) -> bytes: """ Generate the redeem script for the multisig output @@ -41,6 +39,7 @@ def generate_multisig_redeem_script(signatures_required: int, public_key_bytes: :return: The redeem script for the multisig wallet :rtype: bytes """ + settings = get_settings() if signatures_required > settings.MAX_MULTISIG_SIGNATURES: raise ValueError('Signatures required {} is over the limit'.format(signatures_required)) if len(public_key_bytes) > settings.MAX_MULTISIG_PUBKEYS: @@ -55,7 +54,7 @@ def generate_multisig_redeem_script(signatures_required: int, public_key_bytes: return redeem_script.data -def generate_multisig_address(redeem_script: bytes, version_byte: bytes = settings.MULTISIG_VERSION_BYTE) -> str: +def generate_multisig_address(redeem_script: bytes, version_byte: Optional[bytes] = None) -> str: """ Generate a multisig address for the multisig wallet @@ -72,9 +71,11 @@ def generate_multisig_address(redeem_script: bytes, version_byte: bytes = settin :return: The multisig address :rtype: str(base58) """ + settings = get_settings() + actual_version_byte: bytes = version_byte if version_byte is not None else settings.MULTISIG_VERSION_BYTE address = bytearray() - address.extend(version_byte) + address.extend(actual_version_byte) redeem_script_hash = get_hash160(redeem_script) address.extend(redeem_script_hash) From 4b34cb459eba1100daae5f2668b003dbc0ef7bbd Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Thu, 21 Sep 2023 18:56:44 -0300 Subject: [PATCH 09/26] chore(python): drop support for Python 3.9 --- .github/workflows/docker.yml | 1 - .github/workflows/main.yml | 2 +- hathor/cli/run_node.py | 2 +- poetry.lock | 16 +++++++++++++--- pyproject.toml | 3 +-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 624cd4b0d..7e121df01 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -24,7 +24,6 @@ jobs: - python - pypy python-version: - - '3.9' - '3.10' - '3.11' exclude: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4347c377f..7e35fced5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: import os import json full_matrix = { - 'python': ['3.9', '3.10', '3.11'], + 'python': ['3.10', '3.11'], # available OS's: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on 'os': ['ubuntu-22.04', 'macos-12', 'windows-2022'], 'include': [ diff --git a/hathor/cli/run_node.py b/hathor/cli/run_node.py index eb16f5bd1..06fefd4c1 100644 --- a/hathor/cli/run_node.py +++ b/hathor/cli/run_node.py @@ -313,7 +313,7 @@ def check_unsafe_arguments(self) -> None: def check_python_version(self) -> None: # comments to help grep's - MIN_VER = (3, 9) # Python-3.9 + MIN_VER = (3, 10) # Python-3.10 MIN_STABLE = (3, 10) # Python-3.10 RECOMMENDED_VER = (3, 10) # Python-3.10 cur = sys.version_info diff --git a/poetry.lock b/poetry.lock index b977d1f2d..1ab969ea7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiohttp" @@ -1410,6 +1410,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1417,8 +1418,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1435,6 +1443,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1442,6 +1451,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2125,5 +2135,5 @@ sentry = ["sentry-sdk", "structlog-sentry"] [metadata] lock-version = "2.0" -python-versions = ">=3.9,<4" -content-hash = "6ff762cf3cfa31bece485b6db166cea7a2f08f16b1d9111a08607d3959b93ba4" +python-versions = ">=3.10,<4" +content-hash = "62d54c9d748647746f20a2bfb84163143d744915c15138256561b29186386807" diff --git a/pyproject.toml b/pyproject.toml index 78c782e6a..ea6aa1f9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ homepage = "https://hathor.network/" repository = "https://github.com/HathorNetwork/hathor-core/" # https://pypi.org/classifiers/ classifiers = [ - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Operating System :: OS Independent", @@ -51,7 +50,7 @@ types-pyopenssl = "=22.1.0.2" types-pyyaml = "=6.0.12.9" [tool.poetry.dependencies] -python = ">=3.9,<4" +python = ">=3.10,<4" twisted = "~22.10.0" autobahn = "~23.6.2" base58 = "~2.1.1" From e2d9278a92c4801ae2f3986783a4dba6d237e73e Mon Sep 17 00:00:00 2001 From: Marcelo Salhab Brogliato Date: Fri, 22 Sep 2023 00:21:59 -0500 Subject: [PATCH 10/26] feat(p2p): Add ping salt and improve rtt information --- hathor/p2p/resources/status.py | 1 + hathor/p2p/states/ready.py | 43 ++++++++++++++++++++++++---------- tests/p2p/test_protocol.py | 14 +++++------ 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/hathor/p2p/resources/status.py b/hathor/p2p/resources/status.py index 0d1434771..35a722e69 100644 --- a/hathor/p2p/resources/status.py +++ b/hathor/p2p/resources/status.py @@ -69,6 +69,7 @@ def render_GET(self, request): 'address': '{}:{}'.format(remote.host, remote.port), 'state': conn.state.state_name, # 'received_bytes': conn.received_bytes, + 'rtt': list(conn.state.rtt_window), 'last_message': time.time() - conn.last_message, 'plugins': status, 'warning_flags': [flag.value for flag in conn.warning_flags], diff --git a/hathor/p2p/states/ready.py b/hathor/p2p/states/ready.py index 91e58a563..a93727719 100644 --- a/hathor/p2p/states/ready.py +++ b/hathor/p2p/states/ready.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from math import inf +from collections import deque from typing import TYPE_CHECKING, Iterable, Optional from structlog import get_logger @@ -53,14 +53,18 @@ def __init__(self, protocol: 'HathorProtocol') -> None: # Time we sent last PING message. self.ping_start_time: Optional[float] = None + # Salt used in the last PING message. + self.ping_salt: Optional[str] = None + + # Salt size in bytes. + self.ping_salt_size: int = 32 + # Time we got last PONG response to a PING message. self.ping_last_response: float = 0 # Round-trip time of the last PING/PONG. - self.ping_rtt: float = inf - - # Minimum round-trip time among PING/PONG. - self.ping_min_rtt: float = inf + self.rtt_window: deque[float] = deque() + self.MAX_RTT_WINDOW: int = 200 # Last 200 samples (~= 10 minutes) # The last blocks from the best blockchain in the peer self.peer_best_blockchain: list[HeightInfo] = [] @@ -146,7 +150,7 @@ def handle_get_peers(self, payload: str) -> None: self.send_peers(self.protocol.connections.iter_ready_connections()) def send_peers(self, connections: Iterable['HathorProtocol']) -> None: - """ Send a PEERS command with a list of all known peers. + """ Send a PEERS command with a list of all connected peers. """ peers = [] for conn in connections: @@ -185,28 +189,41 @@ def send_ping(self) -> None: """ Send a PING command. Usually you would use `send_ping_if_necessary` to prevent wasting bandwidth. """ + # Add a salt number to prevent peers from faking rtt. self.ping_start_time = self.reactor.seconds() - self.send_message(ProtocolMessages.PING) + rng = self.protocol.connections.rng + self.ping_salt = rng.randbytes(self.ping_salt_size).hex() + self.send_message(ProtocolMessages.PING, self.ping_salt) - def send_pong(self) -> None: + def send_pong(self, salt: str) -> None: """ Send a PONG command as a response to a PING command. """ - self.send_message(ProtocolMessages.PONG) + self.send_message(ProtocolMessages.PONG, salt) def handle_ping(self, payload: str) -> None: """Executed when a PING command is received. It responds with a PONG message.""" - self.send_pong() + self.send_pong(payload) def handle_pong(self, payload: str) -> None: """Executed when a PONG message is received.""" if self.ping_start_time is None: # This should never happen. return + if self.ping_salt != payload: + # Ignore pong without salts. + return self.ping_last_response = self.reactor.seconds() - self.ping_rtt = self.ping_last_response - self.ping_start_time - self.ping_min_rtt = min(self.ping_min_rtt, self.ping_rtt) + rtt = self.ping_last_response - self.ping_start_time + self.rtt_window.appendleft(rtt) + if len(self.rtt_window) > self.MAX_RTT_WINDOW: + self.rtt_window.pop() self.ping_start_time = None - self.log.debug('rtt updated', rtt=self.ping_rtt, min_rtt=self.ping_min_rtt) + self.ping_salt = None + self.log.debug('rtt updated', + latest=rtt, + min=min(self.rtt_window), + max=max(self.rtt_window), + avg=sum(self.rtt_window) / len(self.rtt_window)) def send_get_best_blockchain(self, n_blocks: Optional[int] = None) -> None: """ Send a GET-BEST-BLOCKCHAIN command, requesting a list of the latest diff --git a/tests/p2p/test_protocol.py b/tests/p2p/test_protocol.py index fc08d52cc..8ce4f85b0 100644 --- a/tests/p2p/test_protocol.py +++ b/tests/p2p/test_protocol.py @@ -356,14 +356,14 @@ def test_send_ping(self): self.conn.run_one_step() # TIPS self.assertIsConnected() self.clock.advance(5) - self.assertEqual(b'PING\r\n', self.conn.peek_tr1_value()) - self.assertEqual(b'PING\r\n', self.conn.peek_tr2_value()) + self.assertRegex(self.conn.peek_tr1_value(), b'^PING .*\r\n') + self.assertRegex(self.conn.peek_tr2_value(), b'^PING .*\r\n') self.conn.run_one_step() # PING self.conn.run_one_step() # GET-TIPS self.conn.run_one_step() # GET-BEST-BLOCKCHAIN - self.assertEqual(b'PONG\r\n', self.conn.peek_tr1_value()) - self.assertEqual(b'PONG\r\n', self.conn.peek_tr2_value()) - while b'PONG\r\n' in self.conn.peek_tr1_value(): + self.assertRegex(self.conn.peek_tr1_value(), b'PONG .*\r\n') + self.assertRegex(self.conn.peek_tr2_value(), b'PONG .*\r\n') + while b'PONG ' in self.conn.peek_tr1_value(): self.conn.run_one_step() self.assertEqual(self.clock.seconds(), self.conn.proto1.last_message) @@ -489,8 +489,8 @@ def test_send_ping(self): self.assertAndStepConn(self.conn, b'^TIPS') self.assertAndStepConn(self.conn, b'^TIPS') self.assertAndStepConn(self.conn, b'^TIPS-END') - self.assertEqual(b'PONG\r\n', self.conn.peek_tr1_value()) - self.assertEqual(b'PONG\r\n', self.conn.peek_tr2_value()) + self.assertRegex(self.conn.peek_tr1_value(), b'^PONG .*\r\n') + self.assertRegex(self.conn.peek_tr2_value(), b'^PONG .*\r\n') while b'PONG\r\n' in self.conn.peek_tr1_value(): self.conn.run_one_step() self.assertEqual(self.clock.seconds(), self.conn.proto1.last_message) From 1f5ecccead6144f4621e0fb3134b5d8d5c91530a Mon Sep 17 00:00:00 2001 From: Alex Ruzenhack Date: Fri, 28 Jul 2023 20:18:11 +0100 Subject: [PATCH 11/26] feat: add --sysctl-init-file as cli command option --- hathor/builder/sysctl_builder.py | 1 + hathor/cli/run_node.py | 17 ++- hathor/sysctl/init_file_loader.py | 18 +++ hathor/sysctl/runner.py | 1 + tests/cli/test_sysctl_init.py | 200 ++++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 hathor/sysctl/init_file_loader.py create mode 100644 tests/cli/test_sysctl_init.py diff --git a/hathor/builder/sysctl_builder.py b/hathor/builder/sysctl_builder.py index 60b2cb0ed..46c189ebd 100644 --- a/hathor/builder/sysctl_builder.py +++ b/hathor/builder/sysctl_builder.py @@ -18,6 +18,7 @@ class SysctlBuilder: """Builder for the sysctl tree.""" + def __init__(self, artifacts: BuildArtifacts) -> None: self.artifacts = artifacts diff --git a/hathor/cli/run_node.py b/hathor/cli/run_node.py index 06fefd4c1..00ab40956 100644 --- a/hathor/cli/run_node.py +++ b/hathor/cli/run_node.py @@ -15,7 +15,7 @@ import os import sys from argparse import SUPPRESS, ArgumentParser, Namespace -from typing import Any, Callable +from typing import Any, Callable, Optional from pydantic import ValidationError from structlog import get_logger @@ -58,6 +58,8 @@ def create_parser(cls) -> ArgumentParser: parser.add_argument('--peer', help='json file with peer info') parser.add_argument('--sysctl', help='Endpoint description (eg: unix:/path/sysctl.sock, tcp:5000:interface:127.0.0.1)') + parser.add_argument('--sysctl-init-file', + help='File path to the sysctl.txt init file (eg: conf/sysctl.txt)') parser.add_argument('--listen', action='append', default=[], help='Address to listen for new connections (eg: tcp:8000)') parser.add_argument('--bootstrap', action='append', help='Address to connect to (eg: tcp:127.0.0.1:8000') @@ -371,10 +373,10 @@ def __init__(self, *, argv=None): self.prepare() self.register_signal_handlers() if self._args.sysctl: - self.init_sysctl(self._args.sysctl) + self.init_sysctl(self._args.sysctl, self._args.sysctl_init_file) - def init_sysctl(self, description: str) -> None: - """Initialize sysctl and listen for connections. + def init_sysctl(self, description: str, sysctl_init_file: Optional[str] = None) -> None: + """Initialize sysctl, listen for connections and apply settings from config file if required. Examples of description: - tcp:5000 @@ -389,12 +391,17 @@ def init_sysctl(self, description: str) -> None: from hathor.builder.sysctl_builder import SysctlBuilder from hathor.sysctl.factory import SysctlFactory + from hathor.sysctl.init_file_loader import SysctlInitFileLoader from hathor.sysctl.runner import SysctlRunner builder = SysctlBuilder(self.artifacts) root = builder.build() - runner = SysctlRunner(root) + + if sysctl_init_file: + init_file_loader = SysctlInitFileLoader(runner, sysctl_init_file) + init_file_loader.load() + factory = SysctlFactory(runner) endpoint = serverFromString(self.reactor, description) endpoint.listen(factory) diff --git a/hathor/sysctl/init_file_loader.py b/hathor/sysctl/init_file_loader.py new file mode 100644 index 000000000..9bf09efb6 --- /dev/null +++ b/hathor/sysctl/init_file_loader.py @@ -0,0 +1,18 @@ +from hathor.sysctl.runner import SysctlRunner + + +class SysctlInitFileLoader: + def __init__(self, runner: SysctlRunner, init_file: str) -> None: + assert runner + assert init_file + + self.runner = runner + self.init_file = init_file + + def load(self) -> None: + """Read the init_file and execute each line as a syctl command in the runner.""" + with open(self.init_file, 'r', encoding='utf-8') as file: + lines = file.readlines() + + for line in lines: + self.runner.run(line.strip()) diff --git a/hathor/sysctl/runner.py b/hathor/sysctl/runner.py index 85850b2db..ef75a21b6 100644 --- a/hathor/sysctl/runner.py +++ b/hathor/sysctl/runner.py @@ -75,6 +75,7 @@ def deserialize(self, value_str: str) -> Any: """Deserialize a value sent by the client.""" if len(value_str) == 0: return () + parts = [x.strip() for x in value_str.split(',')] if len(parts) > 1: return tuple(json.loads(x) for x in parts) diff --git a/tests/cli/test_sysctl_init.py b/tests/cli/test_sysctl_init.py new file mode 100644 index 000000000..a696e2008 --- /dev/null +++ b/tests/cli/test_sysctl_init.py @@ -0,0 +1,200 @@ +import json +import shutil +import tempfile +from pathlib import Path +from unittest.mock import Mock, patch + +from hathor.builder.sysctl_builder import SysctlBuilder +from hathor.cli.run_node import RunNode +from hathor.sysctl.exception import SysctlEntryNotFound, SysctlRunnerException +from hathor.sysctl.init_file_loader import SysctlInitFileLoader +from hathor.sysctl.runner import SysctlRunner +from tests import unittest + + +class SysctlInitTest(unittest.TestCase): + + def setUp(self): + super().setUp() + self.tmp_dir = tempfile.mkdtemp() + + def tearDown(self): + super().tearDown() + # Removing tmpdir + shutil.rmtree(self.tmp_dir) + + def test_sysctl_builder_fail_with_invalid_property(self): + file_content = [ + 'invalid.property=10', + ] + + with tempfile.NamedTemporaryFile( + dir=self.tmp_dir, + suffix='.txt', + prefix='sysctl_', + delete=False) as sysctl_init_file: + sysctl_init_file.write('\n'.join(file_content).encode()) + sysctl_init_file_path = str(Path(sysctl_init_file.name)) + + # prepare to register only p2p commands + artifacts = Mock(**{ + 'p2p_manager': Mock(), + 'manager.metrics.websocket_factory.return_value': None + }) + + with self.assertRaises(SysctlEntryNotFound) as context: + root = SysctlBuilder(artifacts).build() + runner = SysctlRunner(root) + loader = SysctlInitFileLoader(runner, sysctl_init_file_path) + loader.load() + + # assert message in the caught exception + expected_msg = 'invalid.property' + self.assertEqual(str(context.exception), expected_msg) + + def test_sysctl_builder_fail_with_invalid_value(self): + file_content = [ + 'p2p.rate_limit.global.send_tips=!!tuple [1,2]' + ] + + with tempfile.NamedTemporaryFile( + dir=self.tmp_dir, + suffix='.txt', + prefix='sysctl_', + delete=False) as sysctl_init_file: + sysctl_init_file.write('\n'.join(file_content).encode()) + sysctl_init_file_path = str(Path(sysctl_init_file.name)) + + # prepare to register only p2p commands + artifacts = Mock(**{ + 'p2p_manager': Mock(), + 'manager.metrics.websocket_factory.return_value': None + }) + + with self.assertRaises(SysctlRunnerException) as context: + root = SysctlBuilder(artifacts).build() + runner = SysctlRunner(root) + loader = SysctlInitFileLoader(runner, sysctl_init_file_path) + loader.load() + + # assert message in the caught exception + expected_msg = 'value: wrong format' + self.assertEqual(str(context.exception), expected_msg) + + def test_syctl_init_file_fail_with_empty_or_invalid_file(self): + # prepare to register only p2p commands + artifacts = Mock(**{ + 'p2p_manager': Mock(), + 'manager.metrics.websocket_factory.return_value': None + }) + + with self.assertRaises(AssertionError): + root = SysctlBuilder(artifacts).build() + runner = SysctlRunner(root) + loader = SysctlInitFileLoader(runner, None) + loader.load() + + with self.assertRaises(AssertionError): + root = SysctlBuilder(artifacts).build() + runner = SysctlRunner(root) + loader = SysctlInitFileLoader(runner, "") + loader.load() + + @patch('twisted.internet.endpoints.serverFromString') # avoid open sock + def test_command_option_sysctl_init_file(self, mock_endpoint): + class CustomRunNode(RunNode): + def start_manager(self) -> None: + pass + + def register_signal_handlers(self) -> None: + pass + + expected_sysctl_dict = { + 'p2p.max_enabled_sync': 7, + 'p2p.rate_limit.global.send_tips': (5, 3), + 'p2p.sync_update_interval': 17, + } + + file_content = [ + 'p2p.max_enabled_sync=7', + 'p2p.rate_limit.global.send_tips=5,3', + 'p2p.sync_update_interval=17', + ] + + with tempfile.NamedTemporaryFile( + dir=self.tmp_dir, + suffix='.txt', + prefix='sysctl_', + delete=False) as sysctl_init_file: + sysctl_init_file.write('\n'.join(file_content).encode()) + sysctl_init_file_path = str(Path(sysctl_init_file.name)) + + run_node = CustomRunNode(argv=[ + '--sysctl', 'tcp:8181', + '--sysctl-init-file', sysctl_init_file_path, # relative to src/hathor + '--memory-storage', + ]) + self.assertTrue(run_node is not None) + conn = run_node.manager.connections + + curr_max_enabled_sync = conn.MAX_ENABLED_SYNC + self.assertEqual( + curr_max_enabled_sync, + expected_sysctl_dict['p2p.max_enabled_sync']) + + curr_rate_limit_global_send_tips = conn.rate_limiter.get_limit(conn.GlobalRateLimiter.SEND_TIPS) + self.assertEqual( + curr_rate_limit_global_send_tips.max_hits, + expected_sysctl_dict['p2p.rate_limit.global.send_tips'][0]) + self.assertEqual( + curr_rate_limit_global_send_tips.window_seconds, + expected_sysctl_dict['p2p.rate_limit.global.send_tips'][1]) + + curr_sync_update_interval = conn.lc_sync_update_interval + self.assertEqual( + curr_sync_update_interval, + expected_sysctl_dict['p2p.sync_update_interval']) + + # assert always_enabled_sync when it is set with a file + expected_sysctl_dict = { + 'p2p.always_enable_sync': ['peer-3', 'peer-4'], + } + + file_content = [ + 'peer-3', + 'peer-4', + ] + + # set the always_enabled_sync peers file + with tempfile.NamedTemporaryFile( + dir=self.tmp_dir, + suffix='.txt', + prefix='always_enable_sync_', + delete=False) as always_enabled_peers_file: + always_enabled_peers_file.write('\n'.join(file_content).encode()) + always_enabled_peers_file_path = str(Path(always_enabled_peers_file.name)) + + file_content = [ + f'p2p.always_enable_sync.readtxt={json.dumps(always_enabled_peers_file_path)}' + ] + + # set the sysctl.txt file + with tempfile.NamedTemporaryFile( + dir=self.tmp_dir, + suffix='.txt', + prefix='sysctl_', + delete=False) as sysctl_init_file: + sysctl_init_file.write('\n'.join(file_content).encode()) + sysctl_init_file_path = str(Path(sysctl_init_file.name)) + + run_node = CustomRunNode(argv=[ + '--sysctl', 'tcp:8181', + '--sysctl-init-file', sysctl_init_file_path, # relative to src/hathor + '--memory-storage', + ]) + self.assertTrue(run_node is not None) + conn = run_node.manager.connections + + curr_always_enabled_sync = list(conn.always_enable_sync) + self.assertTrue( + set(curr_always_enabled_sync).issuperset(set(expected_sysctl_dict['p2p.always_enable_sync']))) From fe3c2e905c6d3bc0ffd95306d9ff66904503a54c Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 22 Sep 2023 01:00:42 -0300 Subject: [PATCH 12/26] refactor(verification): move vertex verification to its own service --- hathor/builder/builder.py | 16 +++ hathor/builder/cli_builder.py | 6 +- hathor/manager.py | 25 +++- hathor/p2p/sync_v2/agent.py | 2 +- hathor/transaction/base_transaction.py | 66 ----------- hathor/transaction/block.py | 27 ----- hathor/transaction/token_creation_tx.py | 8 -- hathor/transaction/transaction.py | 33 ------ hathor/verification/__init__.py | 0 hathor/verification/block_verification.py | 47 ++++++++ ...token_creation_transaction_verification.py | 25 ++++ .../verification/transaction_verification.py | 53 +++++++++ hathor/verification/verification_service.py | 112 ++++++++++++++++++ hathor/wallet/resources/send_tokens.py | 2 +- .../resources/thin_wallet/send_tokens.py | 4 +- tests/consensus/test_consensus.py | 8 +- tests/event/test_event_reorg.py | 2 +- tests/p2p/test_sync.py | 4 +- tests/p2p/test_sync_mempool.py | 4 +- tests/tx/test_blockchain.py | 10 +- tests/tx/test_indexes.py | 2 +- tests/tx/test_reward_lock.py | 10 +- tests/tx/test_tips.py | 2 +- tests/tx/test_tokens.py | 52 ++++---- tests/tx/test_tx.py | 38 +++--- tests/tx/test_tx_storage.py | 6 +- tests/utils.py | 8 +- tests/wallet/test_balance_update.py | 2 +- tests/wallet/test_wallet.py | 2 +- tests/wallet/test_wallet_hd.py | 2 +- 30 files changed, 357 insertions(+), 221 deletions(-) create mode 100644 hathor/verification/__init__.py create mode 100644 hathor/verification/block_verification.py create mode 100644 hathor/verification/token_creation_transaction_verification.py create mode 100644 hathor/verification/transaction_verification.py create mode 100644 hathor/verification/verification_service.py diff --git a/hathor/builder/builder.py b/hathor/builder/builder.py index 0773347ed..3a4631476 100644 --- a/hathor/builder/builder.py +++ b/hathor/builder/builder.py @@ -41,6 +41,7 @@ TransactionStorage, ) from hathor.util import Random, Reactor, get_environment_info +from hathor.verification.verification_service import VerificationService from hathor.wallet import BaseWallet, Wallet logger = get_logger() @@ -101,6 +102,8 @@ def __init__(self) -> None: self._feature_service: Optional[FeatureService] = None self._bit_signaling_service: Optional[BitSignalingService] = None + self._verification_service: Optional[VerificationService] = None + self._rocksdb_path: Optional[str] = None self._rocksdb_storage: Optional[RocksDBStorage] = None self._rocksdb_cache_capacity: Optional[int] = None @@ -157,6 +160,7 @@ def build(self) -> BuildArtifacts: tx_storage = self._get_or_create_tx_storage(indexes) feature_service = self._get_or_create_feature_service(tx_storage) bit_signaling_service = self._get_or_create_bit_signaling_service(tx_storage) + verification_service = self._get_or_create_verification_service() if self._enable_address_index: indexes.enable_address_index(pubsub) @@ -191,6 +195,7 @@ def build(self) -> BuildArtifacts: environment_info=get_environment_info(self._cmdline, peer_id.id), feature_service=feature_service, bit_signaling_service=bit_signaling_service, + verification_service=verification_service, **kwargs ) @@ -424,6 +429,12 @@ def _get_or_create_bit_signaling_service(self, tx_storage: TransactionStorage) - return self._bit_signaling_service + def _get_or_create_verification_service(self) -> VerificationService: + if self._verification_service is None: + self._verification_service = VerificationService() + + return self._verification_service + def use_memory(self) -> 'Builder': self.check_if_can_modify() self._storage_type = StorageType.MEMORY @@ -516,6 +527,11 @@ def set_event_storage(self, event_storage: EventStorage) -> 'Builder': self._event_storage = event_storage return self + def set_verification_service(self, verification_service: VerificationService) -> 'Builder': + self.check_if_can_modify() + self._verification_service = verification_service + return self + def set_reactor(self, reactor: Reactor) -> 'Builder': self.check_if_can_modify() self._reactor = reactor diff --git a/hathor/builder/cli_builder.py b/hathor/builder/cli_builder.py index d71a932a2..1f2e6f7b1 100644 --- a/hathor/builder/cli_builder.py +++ b/hathor/builder/cli_builder.py @@ -35,6 +35,7 @@ from hathor.pubsub import PubSubManager from hathor.stratum import StratumFactory from hathor.util import Random, Reactor +from hathor.verification.verification_service import VerificationService from hathor.wallet import BaseWallet, HDWallet, Wallet logger = get_logger() @@ -202,6 +203,8 @@ def create_manager(self, reactor: Reactor) -> HathorManager: not_support_features=self._args.signal_not_support ) + verification_service = VerificationService() + p2p_manager = ConnectionsManager( reactor, network=network, @@ -231,7 +234,8 @@ def create_manager(self, reactor: Reactor) -> HathorManager: full_verification=full_verification, enable_event_queue=self._args.x_enable_event_queue, feature_service=self.feature_service, - bit_signaling_service=bit_signaling_service + bit_signaling_service=bit_signaling_service, + verification_service=verification_service, ) p2p_manager.set_manager(self.manager) diff --git a/hathor/manager.py b/hathor/manager.py index 4f6284217..99f46cc5e 100644 --- a/hathor/manager.py +++ b/hathor/manager.py @@ -57,6 +57,7 @@ from hathor.transaction.storage.tx_allow_scope import TxAllowScope from hathor.types import Address, VertexId from hathor.util import EnvironmentInfo, LogDuration, Random, Reactor, calculate_min_significant_weight, not_none +from hathor.verification.verification_service import VerificationService from hathor.wallet import BaseWallet settings = HathorSettings() @@ -102,6 +103,7 @@ def __init__(self, event_manager: EventManager, feature_service: FeatureService, bit_signaling_service: BitSignalingService, + verification_service: VerificationService, network: str, hostname: Optional[str] = None, wallet: Optional[BaseWallet] = None, @@ -177,6 +179,7 @@ def __init__(self, self._feature_service = feature_service self._bit_signaling_service = bit_signaling_service + self.verification_service = verification_service self.consensus_algorithm = consensus_algorithm @@ -453,7 +456,10 @@ def _initialize_components_full_verification(self) -> None: tx.calculate_min_height() if tx.is_genesis: assert tx.validate_checkpoint(self.checkpoints) - assert tx.validate_full(skip_block_weight_verification=skip_block_weight_verification) + assert self.verification_service.validate_full( + tx, + skip_block_weight_verification=skip_block_weight_verification + ) self.tx_storage.add_to_indexes(tx) with self.tx_storage.allow_only_valid_context(): self.consensus_algorithm.update(tx) @@ -464,7 +470,10 @@ def _initialize_components_full_verification(self) -> None: self.sync_v2_step_validations([tx], quiet=True) self.tx_storage.save_transaction(tx, only_metadata=True) else: - assert tx.validate_basic(skip_block_weight_verification=skip_block_weight_verification) + assert self.verification_service.validate_basic( + tx, + skip_block_weight_verification=skip_block_weight_verification + ) self.tx_storage.save_transaction(tx, only_metadata=True) except (InvalidNewTransaction, TxValidationError): self.log.error('unexpected error when initializing', tx=tx, exc_info=True) @@ -919,7 +928,7 @@ def push_tx(self, tx: Transaction, allow_non_standard_script: bool = False, raise NonStandardTxError('Transaction is non standard.') # Validate tx. - success, message = tx.validate_tx_error() + success, message = self.verification_service.validate_vertex_error(tx) if not success: raise InvalidNewTransaction(message) @@ -992,7 +1001,7 @@ def on_new_tx(self, tx: BaseTransaction, *, conn: Optional[HathorProtocol] = Non if not metadata.validation.is_fully_connected(): try: - tx.validate_full(reject_locked_reward=reject_locked_reward) + self.verification_service.validate_full(tx, reject_locked_reward=reject_locked_reward) except HathorError as e: if not fails_silently: raise InvalidNewTransaction('full validation failed') from e @@ -1014,7 +1023,11 @@ def on_new_tx(self, tx: BaseTransaction, *, conn: Optional[HathorProtocol] = Non self.log.warn('on_new_tx(): consensus update failed', tx=tx.hash_hex, exc_info=True) return False - assert tx.validate_full(skip_block_weight_verification=True, reject_locked_reward=reject_locked_reward) + assert self.verification_service.validate_full( + tx, + skip_block_weight_verification=True, + reject_locked_reward=reject_locked_reward + ) self.tx_storage.indexes.update(tx) if self.tx_storage.indexes.mempool_tips: self.tx_storage.indexes.mempool_tips.update(tx) # XXX: move to indexes.update @@ -1068,7 +1081,7 @@ def sync_v2_step_validations(self, txs: Iterable[BaseTransaction], *, quiet: boo try: # XXX: `reject_locked_reward` might not apply, partial validation is only used on sync-v2 # TODO: deal with `reject_locked_reward` on sync-v2 - assert tx.validate_full(reject_locked_reward=False) + assert self.verification_service.validate_full(tx, reject_locked_reward=False) except (AssertionError, HathorError): # TODO raise diff --git a/hathor/p2p/sync_v2/agent.py b/hathor/p2p/sync_v2/agent.py index 3ee2baa1f..1d62ee8fc 100644 --- a/hathor/p2p/sync_v2/agent.py +++ b/hathor/p2p/sync_v2/agent.py @@ -1154,7 +1154,7 @@ def on_new_tx(self, tx: BaseTransaction, *, quiet: bool = False, propagate_to_pe if isinstance(tx, Block) and not tx.has_basic_block_parent(): self.log.warn('on_new_tx(): block parent needs to be at least basic-valid', tx=tx.hash_hex) return False - if not tx.validate_basic(): + if not self.manager.verification_service.validate_basic(tx): self.log.warn('on_new_tx(): basic validation failed', tx=tx.hash_hex) return False diff --git a/hathor/transaction/base_transaction.py b/hathor/transaction/base_transaction.py index f4a3eb358..0e4b2eee5 100644 --- a/hathor/transaction/base_transaction.py +++ b/hathor/transaction/base_transaction.py @@ -39,7 +39,6 @@ TimestampError, TooManyOutputs, TooManySigOps, - TxValidationError, WeightError, ) from hathor.transaction.transaction_metadata import TransactionMetadata @@ -514,42 +513,6 @@ def validate_checkpoint(self, checkpoints: list[Checkpoint]) -> bool: self.set_validation(ValidationState.CHECKPOINT) return True - def validate_basic(self, skip_block_weight_verification: bool = False) -> bool: - """ Run basic validations (all that are possible without dependencies) and update the validation state. - - If no exception is raised, the ValidationState will end up as `BASIC` and return `True`. - """ - self.verify_basic(skip_block_weight_verification=skip_block_weight_verification) - self.set_validation(ValidationState.BASIC) - return True - - def validate_full(self, skip_block_weight_verification: bool = False, sync_checkpoints: bool = False, - reject_locked_reward: bool = True) -> bool: - """ Run full validations (these need access to all dependencies) and update the validation state. - - If no exception is raised, the ValidationState will end up as `FULL` or `CHECKPOINT_FULL` and return `True`. - """ - from hathor.transaction.transaction_metadata import ValidationState - - meta = self.get_metadata() - - # skip full validation when it is a checkpoint - if meta.validation.is_checkpoint(): - self.set_validation(ValidationState.CHECKPOINT_FULL) - return True - - # XXX: in some cases it might be possible that this transaction is verified by a checkpoint but we went - # directly into trying a full validation so we should check it here to make sure the validation states - # ends up being CHECKPOINT_FULL instead of FULL - if not meta.validation.is_at_least_basic(): - # run basic validation if we haven't already - self.verify_basic(skip_block_weight_verification=skip_block_weight_verification) - - self.verify(reject_locked_reward=reject_locked_reward) - validation = ValidationState.CHECKPOINT_FULL if sync_checkpoints else ValidationState.FULL - self.set_validation(validation) - return True - def _mark_partially_validated(self) -> None: """ This function is used to add the partially-validated mark from the voided-by metadata. @@ -577,20 +540,6 @@ def verify_checkpoint(self, checkpoints: list[Checkpoint]) -> None: To be implemented by tx/block, used by `self.validate_checkpoint`. Should not modify the validation state.""" raise NotImplementedError - @abstractmethod - def verify_basic(self, skip_block_weight_verification: bool = False) -> None: - """Basic verifications (the ones without access to dependencies: parents+inputs). Raises on error. - - To be implemented by tx/block, used by `self.validate_basic`. Should not modify the validation state.""" - raise NotImplementedError - - @abstractmethod - def verify(self, reject_locked_reward: bool = True) -> None: - """Run all verifications. Raises on error. - - To be implemented by tx/block, used by `self.validate_full`. Should not modify the validation state.""" - raise NotImplementedError - def verify_parents(self) -> None: """All parents must exist and their timestamps must be smaller than ours. @@ -1102,21 +1051,6 @@ def serialize_output(tx: BaseTransaction, tx_out: TxOutput) -> dict[str, Any]: return ret - def validate_tx_error(self) -> tuple[bool, str]: - """ Verify if tx is valid and return success and possible error message - - :return: Success if tx is valid and possible error message, if not - :rtype: tuple[bool, str] - """ - success = True - message = '' - try: - self.verify() - except TxValidationError as e: - success = False - message = str(e) - return success, message - def clone(self) -> 'BaseTransaction': """Return exact copy without sharing memory, including metadata if loaded. diff --git a/hathor/transaction/block.py b/hathor/transaction/block.py index 8ed354842..bef6f3368 100644 --- a/hathor/transaction/block.py +++ b/hathor/transaction/block.py @@ -321,12 +321,6 @@ def has_basic_block_parent(self) -> bool: return False return metadata.validation.is_at_least_basic() - def verify_basic(self, skip_block_weight_verification: bool = False) -> None: - """Partially run validations, the ones that need parents/inputs are skipped.""" - if not skip_block_weight_verification: - self.verify_weight() - self.verify_reward() - def verify_checkpoint(self, checkpoints: list[Checkpoint]) -> None: assert self.hash is not None assert self.storage is not None @@ -396,27 +390,6 @@ def get_base_hash(self) -> bytes: from hathor.merged_mining.bitcoin import sha256d_hash return sha256d_hash(self.get_header_without_nonce()) - @cpu.profiler(key=lambda self: 'block-verify!{}'.format(self.hash.hex())) - def verify(self, reject_locked_reward: bool = True) -> None: - """ - (1) confirms at least two pending transactions and references last block - (2) solves the pow with the correct weight (done in HathorManager) - (3) creates the correct amount of tokens in the output (done in HathorManager) - (4) all parents must exist and have timestamp smaller than ours - (5) data field must contain at most BLOCK_DATA_MAX_SIZE bytes - """ - # TODO Should we validate a limit of outputs? - if self.is_genesis: - # TODO do genesis validation - return - - self.verify_without_storage() - - # (1) and (4) - self.verify_parents() - - self.verify_height() - def get_height(self) -> int: """Returns the block's height.""" meta = self.get_metadata() diff --git a/hathor/transaction/token_creation_tx.py b/hathor/transaction/token_creation_tx.py index f134b9896..c2e63f9f2 100644 --- a/hathor/transaction/token_creation_tx.py +++ b/hathor/transaction/token_creation_tx.py @@ -220,14 +220,6 @@ def to_json_extended(self) -> dict[str, Any]: json['tokens'] = [] return json - def verify(self, reject_locked_reward: bool = True) -> None: - """ Run all validations as regular transactions plus validation on token info. - - We also overload verify_sum to make some different checks - """ - super().verify(reject_locked_reward=reject_locked_reward) - self.verify_token_info() - def verify_sum(self) -> None: """ Besides all checks made on regular transactions, a few extra ones are made: - only HTR tokens on the inputs; diff --git a/hathor/transaction/transaction.py b/hathor/transaction/transaction.py index 98d4bcfc2..626010da2 100644 --- a/hathor/transaction/transaction.py +++ b/hathor/transaction/transaction.py @@ -284,15 +284,6 @@ def to_json(self, decode_script: bool = False, include_metadata: bool = False) - json['tokens'] = [h.hex() for h in self.tokens] return json - def verify_basic(self, skip_block_weight_verification: bool = False) -> None: - """Partially run validations, the ones that need parents/inputs are skipped.""" - if self.is_genesis: - # TODO do genesis validation? - return - self.verify_parents_basic() - self.verify_weight() - self.verify_without_storage() - def verify_checkpoint(self, checkpoints: list[Checkpoint]) -> None: assert self.storage is not None if self.is_genesis: @@ -328,30 +319,6 @@ def verify_weight(self) -> None: raise WeightError(f'Invalid new tx {self.hash_hex}: weight ({self.weight}) is ' f'greater than the maximum allowed ({max_tx_weight})') - @cpu.profiler(key=lambda self: 'tx-verify!{}'.format(self.hash.hex())) - def verify(self, reject_locked_reward: bool = True) -> None: - """ Common verification for all transactions: - (i) number of inputs is at most 256 - (ii) number of outputs is at most 256 - (iii) confirms at least two pending transactions - (iv) solves the pow (we verify weight is correct in HathorManager) - (v) validates signature of inputs - (vi) validates public key and output (of the inputs) addresses - (vii) validate that both parents are valid - (viii) validate input's timestamps - (ix) validate inputs and outputs sum - """ - if self.is_genesis: - # TODO do genesis validation - return - self.verify_without_storage() - self.verify_sigops_input() - self.verify_inputs() # need to run verify_inputs first to check if all inputs exist - self.verify_parents() - self.verify_sum() - if reject_locked_reward: - self.verify_reward_locked() - def verify_unsigned_skip_pow(self) -> None: """ Same as .verify but skipping pow and signature verification.""" self.verify_number_of_inputs() diff --git a/hathor/verification/__init__.py b/hathor/verification/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/hathor/verification/block_verification.py b/hathor/verification/block_verification.py new file mode 100644 index 000000000..3e47aa254 --- /dev/null +++ b/hathor/verification/block_verification.py @@ -0,0 +1,47 @@ +# 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 hathor.profiler import get_cpu_profiler +from hathor.transaction import Block + +cpu = get_cpu_profiler() + + +def verify_basic(block: Block, *, skip_block_weight_verification: bool = False) -> None: + """Partially run validations, the ones that need parents/inputs are skipped.""" + if not skip_block_weight_verification: + block.verify_weight() + block.verify_reward() + + +@cpu.profiler(key=lambda block: 'block-verify!{}'.format(block.hash.hex())) +def verify(block: Block) -> None: + """ + (1) confirms at least two pending transactions and references last block + (2) solves the pow with the correct weight (done in HathorManager) + (3) creates the correct amount of tokens in the output (done in HathorManager) + (4) all parents must exist and have timestamp smaller than ours + (5) data field must contain at most BLOCK_DATA_MAX_SIZE bytes + """ + # TODO Should we validate a limit of outputs? + if block.is_genesis: + # TODO do genesis validation + return + + block.verify_without_storage() + + # (1) and (4) + block.verify_parents() + + block.verify_height() diff --git a/hathor/verification/token_creation_transaction_verification.py b/hathor/verification/token_creation_transaction_verification.py new file mode 100644 index 000000000..b1d9622b2 --- /dev/null +++ b/hathor/verification/token_creation_transaction_verification.py @@ -0,0 +1,25 @@ +# 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 hathor.transaction.token_creation_tx import TokenCreationTransaction +from hathor.verification import transaction_verification + + +def verify(tx: TokenCreationTransaction, *, reject_locked_reward: bool = True) -> None: + """ Run all validations as regular transactions plus validation on token info. + + We also overload verify_sum to make some different checks + """ + transaction_verification.verify(tx, reject_locked_reward=reject_locked_reward) + tx.verify_token_info() diff --git a/hathor/verification/transaction_verification.py b/hathor/verification/transaction_verification.py new file mode 100644 index 000000000..02d887a10 --- /dev/null +++ b/hathor/verification/transaction_verification.py @@ -0,0 +1,53 @@ +# 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 hathor.profiler import get_cpu_profiler +from hathor.transaction import Transaction + +cpu = get_cpu_profiler() + + +def verify_basic(transaction: Transaction) -> None: + """Partially run validations, the ones that need parents/inputs are skipped.""" + if transaction.is_genesis: + # TODO do genesis validation? + return + transaction.verify_parents_basic() + transaction.verify_weight() + transaction.verify_without_storage() + + +@cpu.profiler(key=lambda tx: 'tx-verify!{}'.format(tx.hash.hex())) +def verify(tx: Transaction, *, reject_locked_reward: bool = True) -> None: + """ Common verification for all transactions: + (i) number of inputs is at most 256 + (ii) number of outputs is at most 256 + (iii) confirms at least two pending transactions + (iv) solves the pow (we verify weight is correct in HathorManager) + (v) validates signature of inputs + (vi) validates public key and output (of the inputs) addresses + (vii) validate that both parents are valid + (viii) validate input's timestamps + (ix) validate inputs and outputs sum + """ + if tx.is_genesis: + # TODO do genesis validation + return + tx.verify_without_storage() + tx.verify_sigops_input() + tx.verify_inputs() # need to run verify_inputs first to check if all inputs exist + tx.verify_parents() + tx.verify_sum() + if reject_locked_reward: + tx.verify_reward_locked() diff --git a/hathor/verification/verification_service.py b/hathor/verification/verification_service.py new file mode 100644 index 000000000..2a98cb662 --- /dev/null +++ b/hathor/verification/verification_service.py @@ -0,0 +1,112 @@ +# 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 hathor.transaction import BaseTransaction, Block, Transaction, TxVersion +from hathor.transaction.exceptions import TxValidationError +from hathor.transaction.token_creation_tx import TokenCreationTransaction +from hathor.transaction.validation_state import ValidationState +from hathor.verification import block_verification, token_creation_transaction_verification, transaction_verification + + +class VerificationService: + __slots__ = () + + def validate_basic(self, vertex: BaseTransaction, *, skip_block_weight_verification: bool = False) -> bool: + """ Run basic validations (all that are possible without dependencies) and update the validation state. + + If no exception is raised, the ValidationState will end up as `BASIC` and return `True`. + """ + self.verify_basic(vertex, skip_block_weight_verification=skip_block_weight_verification) + vertex.set_validation(ValidationState.BASIC) + + return True + + def validate_full( + self, + vertex: BaseTransaction, + *, + skip_block_weight_verification: bool = False, + sync_checkpoints: bool = False, + reject_locked_reward: bool = True + ) -> bool: + """ Run full validations (these need access to all dependencies) and update the validation state. + + If no exception is raised, the ValidationState will end up as `FULL` or `CHECKPOINT_FULL` and return `True`. + """ + from hathor.transaction.transaction_metadata import ValidationState + + meta = vertex.get_metadata() + + # skip full validation when it is a checkpoint + if meta.validation.is_checkpoint(): + vertex.set_validation(ValidationState.CHECKPOINT_FULL) + return True + + # XXX: in some cases it might be possible that this transaction is verified by a checkpoint but we went + # directly into trying a full validation so we should check it here to make sure the validation states + # ends up being CHECKPOINT_FULL instead of FULL + if not meta.validation.is_at_least_basic(): + # run basic validation if we haven't already + self.verify_basic(vertex, skip_block_weight_verification=skip_block_weight_verification) + + self.verify(vertex, reject_locked_reward=reject_locked_reward) + validation = ValidationState.CHECKPOINT_FULL if sync_checkpoints else ValidationState.FULL + vertex.set_validation(validation) + return True + + def verify_basic(self, vertex: BaseTransaction, *, skip_block_weight_verification: bool = False) -> None: + """Basic verifications (the ones without access to dependencies: parents+inputs). Raises on error. + + Used by `self.validate_basic`. Should not modify the validation state.""" + match vertex.version: + case TxVersion.REGULAR_BLOCK | TxVersion.MERGE_MINED_BLOCK: + assert isinstance(vertex, Block) + block_verification.verify_basic(vertex, skip_block_weight_verification=skip_block_weight_verification) + case TxVersion.REGULAR_TRANSACTION | TxVersion.TOKEN_CREATION_TRANSACTION: + assert isinstance(vertex, Transaction) + transaction_verification.verify_basic(vertex) + case _: + raise NotImplementedError + + def verify(self, vertex: BaseTransaction, *, reject_locked_reward: bool = True) -> None: + """Run all verifications. Raises on error. + + Used by `self.validate_full`. Should not modify the validation state.""" + match vertex.version: + case TxVersion.REGULAR_BLOCK | TxVersion.MERGE_MINED_BLOCK: + assert isinstance(vertex, Block) + block_verification.verify(vertex) + case TxVersion.REGULAR_TRANSACTION: + assert isinstance(vertex, Transaction) + transaction_verification.verify(vertex, reject_locked_reward=reject_locked_reward) + case TxVersion.TOKEN_CREATION_TRANSACTION: + assert isinstance(vertex, TokenCreationTransaction) + token_creation_transaction_verification.verify(vertex, reject_locked_reward=reject_locked_reward) + case _: + raise NotImplementedError + + def validate_vertex_error(self, vertex: BaseTransaction) -> tuple[bool, str]: + """ Verify if tx is valid and return success and possible error message + + :return: Success if tx is valid and possible error message, if not + :rtype: tuple[bool, str] + """ + success = True + message = '' + try: + self.verify(vertex) + except TxValidationError as e: + success = False + message = str(e) + return success, message diff --git a/hathor/wallet/resources/send_tokens.py b/hathor/wallet/resources/send_tokens.py index 703857e27..cf14f11fd 100644 --- a/hathor/wallet/resources/send_tokens.py +++ b/hathor/wallet/resources/send_tokens.py @@ -128,7 +128,7 @@ def _render_POST_thread(self, values: dict[str, Any], request: Request) -> Union weight = minimum_tx_weight(tx) tx.weight = weight tx.resolve() - tx.verify() + self.manager.verification_service.verify(tx) return tx def _cb_tx_resolve(self, tx, request): diff --git a/hathor/wallet/resources/thin_wallet/send_tokens.py b/hathor/wallet/resources/thin_wallet/send_tokens.py index a932600aa..136791f47 100644 --- a/hathor/wallet/resources/thin_wallet/send_tokens.py +++ b/hathor/wallet/resources/thin_wallet/send_tokens.py @@ -212,7 +212,7 @@ def _stratum_deferred_resolve(self, context: _Context) -> None: def _stratum_thread_verify(self, context: _Context) -> _Context: """ Method to verify the transaction that runs in a separated thread """ - context.tx.verify() + self.manager.verification_service.verify(context.tx) return context def _stratum_timeout(self, result: Failure, timeout: int, *, context: _Context) -> None: @@ -264,7 +264,7 @@ def _should_stop(): if context.should_stop_mining_thread: raise CancelledError() context.tx.update_hash() - context.tx.verify() + self.manager.verification_service.verify(context.tx) return context def _cb_tx_resolve(self, context: _Context) -> None: diff --git a/tests/consensus/test_consensus.py b/tests/consensus/test_consensus.py index a2d64ce22..048a3a440 100644 --- a/tests/consensus/test_consensus.py +++ b/tests/consensus/test_consensus.py @@ -83,7 +83,7 @@ def test_revert_block_high_weight(self): b0 = tb0.generate_mining_block(manager.rng, storage=manager.tx_storage) b0.weight = 10 b0.resolve() - b0.verify() + manager.verification_service.verify(b0) manager.propagate_tx(b0, fails_silently=False) b1 = add_new_block(manager, advance_clock=15) @@ -145,7 +145,7 @@ def test_dont_revert_block_low_weight(self): b0 = manager.generate_mining_block() b0.parents = [blocks[-1].hash, conflicting_tx.hash, conflicting_tx.parents[0]] b0.resolve() - b0.verify() + manager.verification_service.verify(b0) manager.propagate_tx(b0, fails_silently=False) b1 = add_new_block(manager, advance_clock=15) @@ -201,7 +201,7 @@ def test_dont_revert_block_high_weight_transaction_verify_other(self): b0 = tb0.generate_mining_block(manager.rng, storage=manager.tx_storage) b0.weight = 10 b0.resolve() - b0.verify() + manager.verification_service.verify(b0) manager.propagate_tx(b0, fails_silently=False) b1 = add_new_block(manager, advance_clock=15) @@ -255,7 +255,7 @@ def test_dont_revert_block_high_weight_verify_both(self): b0.parents = [b0.parents[0], conflicting_tx.hash, conflicting_tx.parents[0]] b0.weight = 10 b0.resolve() - b0.verify() + manager.verification_service.verify(b0) manager.propagate_tx(b0, fails_silently=False) b1 = add_new_block(manager, advance_clock=15) diff --git a/tests/event/test_event_reorg.py b/tests/event/test_event_reorg.py index ab058f18f..603967052 100644 --- a/tests/event/test_event_reorg.py +++ b/tests/event/test_event_reorg.py @@ -40,7 +40,7 @@ def test_reorg_events(self): b0 = tb0.generate_mining_block(self.manager.rng, storage=self.manager.tx_storage, address=BURN_ADDRESS) b0.weight = 10 b0.resolve() - b0.verify() + self.manager.verification_service.verify(b0) self.manager.propagate_tx(b0, fails_silently=False) self.log.debug('reorg block propagated') self.run_to_completion() diff --git a/tests/p2p/test_sync.py b/tests/p2p/test_sync.py index 72d1d6592..ae8af2bb6 100644 --- a/tests/p2p/test_sync.py +++ b/tests/p2p/test_sync.py @@ -44,7 +44,7 @@ def _add_new_tx(self, address, value): tx.weight = 10 tx.parents = self.manager1.get_new_tx_parents() tx.resolve() - tx.verify() + self.manager1.verification_service.verify(tx) self.manager1.propagate_tx(tx) self.clock.advance(10) return tx @@ -61,7 +61,7 @@ def _add_new_transactions(self, num_txs): def _add_new_block(self, propagate=True): block = self.manager1.generate_mining_block() self.assertTrue(block.resolve()) - block.verify() + self.manager1.verification_service.verify(block) self.manager1.on_new_tx(block, propagate_to_peers=propagate) self.clock.advance(10) return block diff --git a/tests/p2p/test_sync_mempool.py b/tests/p2p/test_sync_mempool.py index 37f8a86fd..ac4fc9bb1 100644 --- a/tests/p2p/test_sync_mempool.py +++ b/tests/p2p/test_sync_mempool.py @@ -32,7 +32,7 @@ def _add_new_tx(self, address, value): tx.weight = 10 tx.parents = self.manager1.get_new_tx_parents() tx.resolve() - tx.verify() + self.manager1.verification_service.verify(tx) self.manager1.propagate_tx(tx) self.clock.advance(10) return tx @@ -49,7 +49,7 @@ def _add_new_transactions(self, num_txs): def _add_new_block(self, propagate=True): block = self.manager1.generate_mining_block() self.assertTrue(block.resolve()) - block.verify() + self.manager1.verification_service.verify(block) self.manager1.on_new_tx(block, propagate_to_peers=propagate) self.clock.advance(10) return block diff --git a/tests/tx/test_blockchain.py b/tests/tx/test_blockchain.py index 622c839aa..d808975e9 100644 --- a/tests/tx/test_blockchain.py +++ b/tests/tx/test_blockchain.py @@ -115,7 +115,7 @@ def test_single_fork_not_best(self): fork_block1 = manager.generate_mining_block() fork_block1.parents = [fork_block1.parents[0]] + fork_block1.parents[:0:-1] fork_block1.resolve() - fork_block1.verify() + manager.verification_service.verify(fork_block1) # Mine 8 blocks in a row blocks = add_new_blocks(manager, 8, advance_clock=15) @@ -167,7 +167,7 @@ def test_single_fork_not_best(self): # This block belongs to case (iv). fork_block3 = manager.generate_mining_block(parent_block_hash=fork_block1.hash) fork_block3.resolve() - fork_block3.verify() + manager.verification_service.verify(fork_block3) self.assertTrue(manager.propagate_tx(fork_block3)) fork_meta3 = fork_block3.get_metadata() self.assertEqual(fork_meta3.voided_by, {fork_block3.hash}) @@ -237,7 +237,7 @@ def test_multiple_forks(self): # Propagate a block connected to the voided chain, case (iii). fork_block2 = manager.generate_mining_block(parent_block_hash=sidechain[-1].hash) fork_block2.resolve() - fork_block2.verify() + manager.verification_service.verify(fork_block2) self.assertTrue(manager.propagate_tx(fork_block2)) sidechain.append(fork_block2) @@ -285,7 +285,7 @@ def test_multiple_forks(self): # Propagate a block connected to the side chain, case (v). fork_block3 = manager.generate_mining_block(parent_block_hash=fork_block2.hash) fork_block3.resolve() - fork_block3.verify() + manager.verification_service.verify(fork_block3) self.assertTrue(manager.propagate_tx(fork_block3)) sidechain.append(fork_block3) @@ -311,7 +311,7 @@ def test_multiple_forks(self): fork_block4 = manager.generate_mining_block(parent_block_hash=sidechain3[-1].hash) fork_block4.weight = 10 fork_block4.resolve() - fork_block4.verify() + manager.verification_service.verify(fork_block4) self.assertTrue(manager.propagate_tx(fork_block4)) sidechain3.append(fork_block4) diff --git a/tests/tx/test_indexes.py b/tests/tx/test_indexes.py index 1a2482821..5227b525d 100644 --- a/tests/tx/test_indexes.py +++ b/tests/tx/test_indexes.py @@ -439,7 +439,7 @@ def check_utxos(*args): block2.timestamp = block1.timestamp block2.weight = 1.2 block2.resolve() - block2.validate_full() + self.manager.verification_service.validate_full(block2) self.manager.propagate_tx(block2, fails_silently=False) self.graphviz.labels[block2.hash] = 'block2' diff --git a/tests/tx/test_reward_lock.py b/tests/tx/test_reward_lock.py index e705d608f..ceb27b90f 100644 --- a/tests/tx/test_reward_lock.py +++ b/tests/tx/test_reward_lock.py @@ -73,7 +73,7 @@ def test_classic_reward_lock(self): tx = self._spend_reward_tx(self.manager, reward_block) self.assertEqual(tx.get_metadata().min_height, unlock_height) with self.assertRaises(RewardLocked): - tx.verify() + self.manager.verification_service.verify(tx) add_new_blocks(self.manager, 1, advance_clock=1) # now it should be spendable @@ -127,7 +127,7 @@ def test_mempool_tx_with_not_enough_height(self): tx = self._spend_reward_tx(self.manager, reward_block) self.assertEqual(tx.get_metadata().min_height, unlock_height) with self.assertRaises(RewardLocked): - tx.verify() + self.manager.verification_service.verify(tx) with self.assertRaises(InvalidNewTransaction): self.assertTrue(self.manager.on_new_tx(tx, fails_silently=False)) @@ -161,12 +161,12 @@ def test_mempool_tx_invalid_after_reorg(self): b0 = tb0.generate_mining_block(self.manager.rng, storage=self.manager.tx_storage) b0.weight = 10 b0.resolve() - b0.verify() + self.manager.verification_service.verify(b0) self.manager.propagate_tx(b0, fails_silently=False) # now the new tx should not pass verification considering the reward lock with self.assertRaises(RewardLocked): - tx.verify() + self.manager.verification_service.verify(tx) # the transaction should have been removed from the mempool self.assertNotIn(tx, self.manager.tx_storage.iter_mempool_from_best_index()) @@ -190,7 +190,7 @@ def test_classic_reward_lock_timestamp_expected_to_fail(self): tx.resolve() self.assertEqual(tx.get_metadata().min_height, unlock_height) with self.assertRaises(RewardLocked): - tx.verify() + self.manager.verification_service.verify(tx) class SyncV1TransactionTest(unittest.SyncV1Params, BaseTransactionTest): diff --git a/tests/tx/test_tips.py b/tests/tx/test_tips.py index cdbd09f5e..6242bebf5 100644 --- a/tests/tx/test_tips.py +++ b/tests/tx/test_tips.py @@ -70,7 +70,7 @@ def test_tips_winner(self): new_block = add_new_block(self.manager, propagate=False) new_block.parents = [new_block.parents[0], tx1.hash, tx3.hash] new_block.resolve() - new_block.verify() + self.manager.verification_service.verify(new_block) self.manager.propagate_tx(new_block, fails_silently=False) self.manager.reactor.advance(10) diff --git a/tests/tx/test_tokens.py b/tests/tx/test_tokens.py index 6af8c24a7..b3b036f2f 100644 --- a/tests/tx/test_tokens.py +++ b/tests/tx/test_tokens.py @@ -54,7 +54,7 @@ def test_tokens_in_block(self): block.resolve() with self.assertRaises(BlockWithTokensError): - block.verify() + self.manager.verification_service.verify(block) def test_tx_token_outputs(self): genesis_block = self.genesis_blocks[0] @@ -74,7 +74,7 @@ def test_tx_token_outputs(self): tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx.resolve() with self.assertRaises(InvalidToken): - tx.verify() + self.manager.verification_service.verify(tx) # with 1 token uid in list tx.tokens = [bytes.fromhex('0023be91834c973d6a6ddd1a0ae411807b7c8ef2a015afb5177ee64b666ce602')] @@ -84,7 +84,7 @@ def test_tx_token_outputs(self): tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx.resolve() with self.assertRaises(InvalidToken): - tx.verify() + self.manager.verification_service.verify(tx) # try hathor authority UTXO output = TxOutput(value, script, 0b10000000) @@ -94,7 +94,7 @@ def test_tx_token_outputs(self): tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx.resolve() with self.assertRaises(InvalidToken): - tx.verify() + self.manager.verification_service.verify(tx) def test_token_transfer(self): wallet = self.manager.wallet @@ -114,7 +114,7 @@ def test_token_transfer(self): public_bytes, signature = wallet.get_input_aux_data(data_to_sign, wallet.get_private_key(self.address_b58)) tx2.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx2.resolve() - tx2.verify() + self.manager.verification_service.verify(tx2) # missing tokens token_output = TxOutput(utxo.value - 1, script, 1) @@ -125,7 +125,7 @@ def test_token_transfer(self): tx3.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx3.resolve() with self.assertRaises(InputOutputMismatch): - tx3.verify() + self.manager.verification_service.verify(tx3) def test_token_mint(self): wallet = self.manager.wallet @@ -157,7 +157,7 @@ def test_token_mint(self): tx2.inputs[0].data = data tx2.inputs[1].data = data tx2.resolve() - tx2.verify() + self.manager.verification_service.verify(tx2) self.manager.propagate_tx(tx2) self.run_to_completion() @@ -193,7 +193,7 @@ def test_token_mint(self): tx3.inputs[0].data = data tx3.resolve() with self.assertRaises(InputOutputMismatch): - tx3.verify() + self.manager.verification_service.verify(tx3) # try to mint and deposit less tokens than necessary mint_amount = 10000000 @@ -219,7 +219,7 @@ def test_token_mint(self): tx4.inputs[1].data = data tx4.resolve() with self.assertRaises(InputOutputMismatch): - tx4.verify() + self.manager.verification_service.verify(tx4) # try to mint using melt authority UTXO _input1 = TxInput(tx.hash, 2, b'') @@ -231,7 +231,7 @@ def test_token_mint(self): tx5.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx5.resolve() with self.assertRaises(InputOutputMismatch): - tx5.verify() + self.manager.verification_service.verify(tx5) def test_token_melt(self): wallet = self.manager.wallet @@ -264,7 +264,7 @@ def test_token_melt(self): tx2.inputs[0].data = data tx2.inputs[1].data = data tx2.resolve() - tx2.verify() + self.manager.verification_service.verify(tx2) self.manager.propagate_tx(tx2) self.run_to_completion() @@ -304,7 +304,7 @@ def test_token_melt(self): tx3.inputs[1].data = data tx3.resolve() with self.assertRaises(InputOutputMismatch): - tx3.verify() + self.manager.verification_service.verify(tx3) # try to melt using mint authority UTXO _input1 = TxInput(tx.hash, 0, b'') @@ -319,7 +319,7 @@ def test_token_melt(self): tx4.inputs[1].data = data tx4.resolve() with self.assertRaises(InputOutputMismatch): - tx4.verify() + self.manager.verification_service.verify(tx4) def test_token_transfer_authority(self): wallet = self.manager.wallet @@ -338,7 +338,7 @@ def test_token_transfer_authority(self): tx2.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx2.resolve() with self.assertRaises(InvalidToken): - tx2.verify() + self.manager.verification_service.verify(tx2) # input with melt and output with mint _input1 = TxInput(tx.hash, 2, b'') @@ -350,7 +350,7 @@ def test_token_transfer_authority(self): tx3.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx3.resolve() with self.assertRaises(InvalidToken): - tx3.verify() + self.manager.verification_service.verify(tx3) def test_token_index_with_conflict(self, mint_amount=0): # create a new token and have a mint operation done. The tx that mints the @@ -403,7 +403,7 @@ def test_token_index_with_conflict(self, mint_amount=0): tx2.inputs[1].data = data tx2.inputs[2].data = data tx2.resolve() - tx2.verify() + self.manager.verification_service.verify(tx2) self.manager.propagate_tx(tx2) self.run_to_completion() @@ -455,39 +455,39 @@ def update_tx(tx): # max token name length tx.token_name = 'a' * settings.MAX_LENGTH_TOKEN_NAME update_tx(tx) - tx.verify() + self.manager.verification_service.verify(tx) # max token symbol length tx.token_symbol = 'a' * settings.MAX_LENGTH_TOKEN_SYMBOL update_tx(tx) - tx.verify() + self.manager.verification_service.verify(tx) # long token name tx.token_name = 'a' * (settings.MAX_LENGTH_TOKEN_NAME + 1) update_tx(tx) with self.assertRaises(TransactionDataError): - tx.verify() + self.manager.verification_service.verify(tx) # long token symbol tx.token_name = 'ValidName' tx.token_symbol = 'a' * (settings.MAX_LENGTH_TOKEN_SYMBOL + 1) update_tx(tx) with self.assertRaises(TransactionDataError): - tx.verify() + self.manager.verification_service.verify(tx) # Hathor token name tx.token_name = settings.HATHOR_TOKEN_NAME tx.token_symbol = 'TST' update_tx(tx) with self.assertRaises(TransactionDataError): - tx.verify() + self.manager.verification_service.verify(tx) # Hathor token symbol tx.token_name = 'Test' tx.token_symbol = settings.HATHOR_TOKEN_SYMBOL update_tx(tx) with self.assertRaises(TransactionDataError): - tx.verify() + self.manager.verification_service.verify(tx) # Token name unicode tx.token_name = 'Test ∞' @@ -495,7 +495,7 @@ def update_tx(tx): token_info = tx.serialize_token_info() TokenCreationTransaction.deserialize_token_info(token_info) update_tx(tx) - tx.verify() + self.manager.verification_service.verify(tx) # Token symbol unicode tx.token_name = 'Test Token' @@ -503,7 +503,7 @@ def update_tx(tx): token_info = tx.serialize_token_info() TokenCreationTransaction.deserialize_token_info(token_info) update_tx(tx) - tx.verify() + self.manager.verification_service.verify(tx) def test_token_mint_zero(self): # try to mint 0 tokens @@ -542,7 +542,7 @@ def test_unknown_authority(self): tx2.inputs[1].data = data tx2.resolve() with self.assertRaises(InvalidToken): - tx2.verify() + self.manager.verification_service.verify(tx2) def test_token_info_serialization(self): tx = create_tokens(self.manager, self.address_b58, mint_amount=500) @@ -595,7 +595,7 @@ def test_block_with_htr_authority(self): block.resolve() with self.assertRaises(InvalidToken): - block.verify() + self.manager.verification_service.verify(block) def test_voided_token_creation(self): tx1 = create_tokens(self.manager, self.address_b58, mint_amount=500, use_genesis=False) diff --git a/tests/tx/test_tx.py b/tests/tx/test_tx.py index 0a18106d3..96cc51ce2 100644 --- a/tests/tx/test_tx.py +++ b/tests/tx/test_tx.py @@ -219,7 +219,7 @@ def test_block_inputs(self): block.resolve() with self.assertRaises(BlockWithInputs): - block.verify() + self.manager.verification_service.verify(block) def test_merge_mined_no_magic(self): from hathor.merged_mining import MAGIC_NUMBER @@ -388,21 +388,21 @@ def test_tx_number_parents(self): # in first test, only with 1 parent tx.resolve() with self.assertRaises(IncorrectParents): - tx.verify() + self.manager.verification_service.verify(tx) # test with 3 parents parents = [tx.hash for tx in self.genesis] tx.parents = parents tx.resolve() with self.assertRaises(IncorrectParents): - tx.verify() + self.manager.verification_service.verify(tx) # 2 parents, 1 tx and 1 block parents = [self.genesis_txs[0].hash, self.genesis_blocks[0].hash] tx.parents = parents tx.resolve() with self.assertRaises(IncorrectParents): - tx.verify() + self.manager.verification_service.verify(tx) def test_block_unknown_parent(self): address = get_address_from_public_key(self.genesis_public_key) @@ -421,7 +421,7 @@ def test_block_unknown_parent(self): block.resolve() with self.assertRaises(ParentDoesNotExist): - block.verify() + self.manager.verification_service.verify(block) def test_block_number_parents(self): address = get_address_from_public_key(self.genesis_public_key) @@ -439,7 +439,7 @@ def test_block_number_parents(self): block.resolve() with self.assertRaises(IncorrectParents): - block.verify() + self.manager.verification_service.verify(block) def test_tx_inputs_out_of_range(self): # we'll try to spend output 3 from genesis transaction, which does not exist @@ -462,7 +462,7 @@ def test_tx_inputs_out_of_range(self): # test with an inexistent index tx.resolve() with self.assertRaises(InexistentInput): - tx.verify() + self.manager.verification_service.verify(tx) # now with index equals of len of outputs _input = [TxInput(genesis_block.hash, len(genesis_block.outputs), data)] @@ -470,7 +470,7 @@ def test_tx_inputs_out_of_range(self): # test with an inexistent index tx.resolve() with self.assertRaises(InexistentInput): - tx.verify() + self.manager.verification_service.verify(tx) # now with inexistent tx hash random_bytes = bytes.fromhex('0000184e64683b966b4268f387c269915cc61f6af5329823a93e3696cb0fe902') @@ -478,7 +478,7 @@ def test_tx_inputs_out_of_range(self): tx.inputs = _input tx.resolve() with self.assertRaises(InexistentInput): - tx.verify() + self.manager.verification_service.verify(tx) def test_tx_inputs_conflict(self): # the new tx inputs will try to spend the same output @@ -501,7 +501,7 @@ def test_tx_inputs_conflict(self): tx.resolve() with self.assertRaises(ConflictingInputs): - tx.verify() + self.manager.verification_service.verify(tx) def test_regular_tx(self): # this should succeed @@ -522,7 +522,7 @@ def test_regular_tx(self): _input.data = P2PKH.create_input_data(public_bytes, signature) tx.resolve() - tx.verify() + self.manager.verification_service.verify(tx) def test_tx_weight_too_high(self): parents = [tx.hash for tx in self.genesis_txs] @@ -557,7 +557,7 @@ def test_weight_nan(self): tx.update_hash() self.assertTrue(isnan(tx.weight)) with self.assertRaises(WeightError): - tx.verify() + self.manager.verification_service.verify(tx) def test_weight_inf(self): # this should succeed @@ -580,7 +580,7 @@ def test_weight_inf(self): tx.update_hash() self.assertTrue(isinf(tx.weight)) with self.assertRaises(WeightError): - tx.verify() + self.manager.verification_service.verify(tx) def test_tx_duplicated_parents(self): # the new tx will confirm the same tx twice @@ -602,7 +602,7 @@ def test_tx_duplicated_parents(self): tx.resolve() with self.assertRaises(DuplicatedParents): - tx.verify() + self.manager.verification_service.verify(tx) def test_update_timestamp(self): parents = [tx for tx in self.genesis_txs] @@ -807,7 +807,7 @@ def test_output_value(self): # 'Manually resolving', to validate verify method tx.hash = bytes.fromhex('012cba011be3c29f1c406f9015e42698b97169dbc6652d1f5e4d5c5e83138858') with self.assertRaises(InvalidOutputValue): - tx.verify() + self.manager.verification_service.verify(tx) # Invalid output value invalid_output = bytes.fromhex('ffffffff') @@ -1039,7 +1039,7 @@ def test_sigops_output_single_above_limit(self) -> None: tx.update_hash() # This calls verify to ensure that verify_sigops_output is being called on verify with self.assertRaises(TooManySigOps): - tx.verify() + self.manager.verification_service.verify(tx) def test_sigops_output_multi_above_limit(self) -> None: genesis_block = self.genesis_blocks[0] @@ -1052,7 +1052,7 @@ def test_sigops_output_multi_above_limit(self) -> None: tx = Transaction(inputs=[_input], outputs=[output2]*num_outputs, storage=self.tx_storage) tx.update_hash() with self.assertRaises(TooManySigOps): - tx.verify() + self.manager.verification_service.verify(tx) def test_sigops_output_single_below_limit(self) -> None: genesis_block = self.genesis_blocks[0] @@ -1089,7 +1089,7 @@ def test_sigops_input_single_above_limit(self) -> None: tx = Transaction(inputs=[input1], outputs=[_output], storage=self.tx_storage) tx.update_hash() with self.assertRaises(TooManySigOps): - tx.verify() + self.manager.verification_service.verify(tx) def test_sigops_input_multi_above_limit(self) -> None: genesis_block = self.genesis_blocks[0] @@ -1104,7 +1104,7 @@ def test_sigops_input_multi_above_limit(self) -> None: tx = Transaction(inputs=[input2]*num_inputs, outputs=[_output], storage=self.tx_storage) tx.update_hash() with self.assertRaises(TooManySigOps): - tx.verify() + self.manager.verification_service.verify(tx) def test_sigops_input_single_below_limit(self) -> None: genesis_block = self.genesis_blocks[0] diff --git a/tests/tx/test_tx_storage.py b/tests/tx/test_tx_storage.py index b4ed5d055..b2f83a0a2 100644 --- a/tests/tx/test_tx_storage.py +++ b/tests/tx/test_tx_storage.py @@ -64,7 +64,7 @@ def setUp(self): self.block = Block(timestamp=MIN_TIMESTAMP, weight=12, outputs=[output], parents=block_parents, nonce=100781, storage=self.tx_storage) self.block.resolve() - self.block.verify() + self.manager.verification_service.verify(self.block) self.block.get_metadata().validation = ValidationState.FULL tx_parents = [tx.hash for tx in self.genesis_txs] @@ -114,7 +114,7 @@ def test_genesis(self): self.assertEqual(1, len(self.genesis_blocks)) self.assertEqual(2, len(self.genesis_txs)) for tx in self.genesis: - tx.verify() + self.manager.verification_service.verify(tx) for tx in self.genesis: tx2 = self.tx_storage.get_transaction(tx.hash) @@ -526,7 +526,7 @@ def _add_new_block(self, parents=None): block.parents = parents block.weight = 10 self.assertTrue(block.resolve()) - block.verify() + self.manager.verification_service.verify(block) self.manager.propagate_tx(block, fails_silently=False) self.reactor.advance(5) return block diff --git a/tests/utils.py b/tests/utils.py index 64c578ea6..2878e60a2 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -204,7 +204,7 @@ def gen_new_tx(manager, address, value, verify=True): tx.parents = manager.get_new_tx_parents(tx.timestamp) tx.resolve() if verify: - tx.verify() + manager.verification_service.verify(tx) return tx @@ -266,7 +266,7 @@ def add_new_block(manager, advance_clock=None, *, parent_block_hash=None, if weight is not None: block.weight = weight block.resolve() - block.validate_full() + manager.verification_service.validate_full(block) if propagate: manager.propagate_tx(block, fails_silently=False) if advance_clock: @@ -554,7 +554,7 @@ def create_tokens(manager: 'HathorManager', address_b58: Optional[str] = None, m tx.resolve() if propagate: - tx.verify() + manager.verification_service.verify(tx) manager.propagate_tx(tx, fails_silently=False) assert isinstance(manager.reactor, Clock) manager.reactor.advance(8) @@ -643,7 +643,7 @@ def add_tx_with_data_script(manager: 'HathorManager', data: list[str], propagate tx.resolve() if propagate: - tx.verify() + manager.verification_service.verify(tx) manager.propagate_tx(tx, fails_silently=False) assert isinstance(manager.reactor, Clock) manager.reactor.advance(8) diff --git a/tests/wallet/test_balance_update.py b/tests/wallet/test_balance_update.py index 652cf5a29..ab2260866 100644 --- a/tests/wallet/test_balance_update.py +++ b/tests/wallet/test_balance_update.py @@ -428,7 +428,7 @@ def test_tokens_balance(self): ) tx2.inputs[0].data = P2PKH.create_input_data(public_bytes, signature) tx2.resolve() - tx2.verify() + self.manager.verification_service.verify(tx2) self.manager.propagate_tx(tx2) self.run_to_completion() # verify balance diff --git a/tests/wallet/test_wallet.py b/tests/wallet/test_wallet.py index d6fdb9a43..5add4f3ad 100644 --- a/tests/wallet/test_wallet.py +++ b/tests/wallet/test_wallet.py @@ -208,7 +208,7 @@ def test_create_token_transaction(self): tx2.timestamp = tx.timestamp + 1 tx2.parents = self.manager.get_new_tx_parents() tx2.resolve() - tx2.verify() + self.manager.verification_service.verify(tx2) self.assertNotEqual(len(tx2.inputs), 0) token_dict = defaultdict(int) diff --git a/tests/wallet/test_wallet_hd.py b/tests/wallet/test_wallet_hd.py index b8807f939..5c18648cb 100644 --- a/tests/wallet/test_wallet_hd.py +++ b/tests/wallet/test_wallet_hd.py @@ -31,7 +31,7 @@ def test_transaction_and_balance(self): new_address = self.wallet.get_unused_address() out = WalletOutputInfo(decode_address(new_address), self.TOKENS, timelock=None) block = add_new_block(self.manager) - block.verify() + self.manager.verification_service.verify(block) utxo = self.wallet.unspent_txs[settings.HATHOR_TOKEN_UID].get((block.hash, 0)) self.assertIsNotNone(utxo) self.assertEqual(self.wallet.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, self.BLOCK_TOKENS)) From 42a51794b33ba49b00473ca3c37f3fd603bf43fc Mon Sep 17 00:00:00 2001 From: Jan Segre Date: Tue, 26 Sep 2023 17:51:12 +0200 Subject: [PATCH 13/26] chore: bump version to v0.57.0 --- hathor/cli/openapi_files/openapi_base.json | 2 +- hathor/version.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hathor/cli/openapi_files/openapi_base.json b/hathor/cli/openapi_files/openapi_base.json index 92d7dd989..8c381595b 100644 --- a/hathor/cli/openapi_files/openapi_base.json +++ b/hathor/cli/openapi_files/openapi_base.json @@ -7,7 +7,7 @@ ], "info": { "title": "Hathor API", - "version": "0.56.0" + "version": "0.57.0" }, "consumes": [ "application/json" diff --git a/hathor/version.py b/hathor/version.py index 0c3ca7621..3003f06e8 100644 --- a/hathor/version.py +++ b/hathor/version.py @@ -19,7 +19,7 @@ from structlog import get_logger -BASE_VERSION = '0.56.0' +BASE_VERSION = '0.57.0' DEFAULT_VERSION_SUFFIX = "local" BUILD_VERSION_FILE_PATH = "./BUILD_VERSION" diff --git a/pyproject.toml b/pyproject.toml index ea6aa1f9b..b9b1004e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ [tool.poetry] name = "hathor" -version = "0.56.0" +version = "0.57.0" description = "Hathor Network full-node" authors = ["Hathor Team "] license = "Apache-2.0" From 57126e4cfd2a45f0ccaa13110894656450fe0cd5 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Thu, 21 Sep 2023 15:08:23 -0300 Subject: [PATCH 14/26] feat(reliable-integration): emit VERTEX_METADATA_CHANGED events in reverse topological order --- hathor/consensus/consensus.py | 2 +- tests/event/test_event_reorg.py | 22 +++-------- .../event/test_event_simulation_scenarios.py | 37 ++++++++++--------- 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/hathor/consensus/consensus.py b/hathor/consensus/consensus.py index 6ffe1acba..307dbe0ff 100644 --- a/hathor/consensus/consensus.py +++ b/hathor/consensus/consensus.py @@ -136,7 +136,7 @@ def _unsafe_update(self, base: BaseTransaction) -> None: reorg_size=reorg_size) # finally signal an index update for all affected transactions - sorted_txs_affected = sorted(context.txs_affected, key=lambda tx: not_none(tx.hash)) + sorted_txs_affected = sorted(context.txs_affected, key=lambda tx: not_none(tx.timestamp), reverse=True) for tx_affected in sorted_txs_affected: assert tx_affected.storage is not None assert tx_affected.storage.indexes is not None diff --git a/tests/event/test_event_reorg.py b/tests/event/test_event_reorg.py index 603967052..7d145482b 100644 --- a/tests/event/test_event_reorg.py +++ b/tests/event/test_event_reorg.py @@ -1,5 +1,3 @@ -from typing import Any - from hathor.conf import HathorSettings from hathor.event.model.event_type import EventType from hathor.event.storage import EventMemoryStorage @@ -54,11 +52,9 @@ def test_reorg_events(self): (EventType.NEW_VERTEX_ACCEPTED, {'hash': settings.GENESIS_TX1_HASH.hex()}), (EventType.NEW_VERTEX_ACCEPTED, {'hash': settings.GENESIS_TX2_HASH.hex()}), (EventType.LOAD_FINISHED, {}), - *sorted_by_hash( - (EventType.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}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': settings.GENESIS_TX2_HASH.hex()}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': settings.GENESIS_TX1_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}), @@ -80,11 +76,9 @@ def test_reorg_events(self): (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}), - *sorted_by_hash( - (EventType.VERTEX_METADATA_CHANGED, {'hash': b0.hash_hex}), - (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[9].hash_hex}), - (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[8].hash_hex}), - ), + (EventType.VERTEX_METADATA_CHANGED, {'hash': b0.hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[9].hash_hex}), + (EventType.VERTEX_METADATA_CHANGED, {'hash': blocks[8].hash_hex}), (EventType.REORG_FINISHED, {}), (EventType.NEW_VERTEX_ACCEPTED, {'hash': b0.hash_hex}), ] @@ -98,10 +92,6 @@ def test_reorg_events(self): self.assertEqual(actual_event.data.dict()[expected_data_key], expected_data_value) -def sorted_by_hash(*events: tuple[EventType, dict[str, Any]]) -> list[tuple[EventType, dict[str, Any]]]: - return sorted(events, key=lambda event: event[1]['hash']) - - class SyncV1EventReorgTest(unittest.SyncV1Params, BaseEventReorgTest): __test__ = True diff --git a/tests/event/test_event_simulation_scenarios.py b/tests/event/test_event_simulation_scenarios.py index e87b91f0e..5b9ba4fc4 100644 --- a/tests/event/test_event_simulation_scenarios.py +++ b/tests/event/test_event_simulation_scenarios.py @@ -79,9 +79,9 @@ def test_single_chain_one_block(self): # LOAD_FINISHED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=8, stream_id=stream_id) # noqa: E501 ] @@ -105,9 +105,9 @@ def test_single_chain_blocks_and_transactions(self): # LOAD_FINISHED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878910.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', '8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f', '32fea29451e575e9e001f55878f4df61a2f6cf0212c4b9cbfb8125691d5377a8', '896593a8103553e6f54c46901f8c14e62618efe7f18c5afd48cf26e96db9e393', '0b71c21b8000f05241283a848b99e38f27a94a188def7ef1b93f8b0828caba49', '97b711632054189cbeb1ef4707b7d48c84e6af9a0395a4484030fb3202e691e3', '6b5e6201d81381a49fa7febe15f46d440360d8e7b1a0ddbe42e59889f32af56e', 'fdc65dbd3675a01a39343dd0c4a05eea471c3bd7015bb96cea0bde7143e24c5d', 'eb3c4684dfad95a5b9d1c88f3463b91fe44bbe7b00e4b810648ca9e9ff5685a6', '1eb8f2c848828831c0e50f13b6ea54cac99494031ebad0318c7b142acb5540b7', 'f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb'], twins=[], accumulated_weight=2.0, score=2.0, first_block='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878910.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', nonce=0, timestamp=1578878910, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['8ab45f3b35f8dc437fb4a246d9b7dd3d3d5cfb7270e516076718a7a94598cf2f'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED and one NEW_VERTEX_ACCEPTED for 10 new blocks @@ -137,13 +137,14 @@ def test_single_chain_blocks_and_transactions(self): # One NEW_VERTEX_ACCEPTED for a new tx EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=31, timestamp=1578878970.5, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new tx (below), and one VERTEX_METADATA_CHANGED for a tx, adding the new tx as spending their output and children # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879030.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=32, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=33, timestamp=1578879030.75, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new tx - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=37, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=34, timestamp=1578879030.75, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each confirmed transaction # noqa E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=35, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=36, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', nonce=0, timestamp=1578879030, version=1, weight=18.4904519466213, inputs=[TxInput(tx_id='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', index=0, spent_output=TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)))], outputs=[TxOutput(value=3400, token_data=0, script='dqkUmkey79Rbhjq4BtHYCm2mT8hDprWIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HLatLcoaATFMqECb5fD5rdW2nF9WGyw9os', timelock=None)), TxOutput(value=2000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.4904519466213, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=37, timestamp=1578879091.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', nonce=0, timestamp=1578878970, version=1, weight=18.656776158409354, inputs=[TxInput(tx_id='9b83e5dbc7145a5a161c34da4bec4e1a64dc02a3f2495a2db78457426c9ee6bf', index=0, spent_output=TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None)))], outputs=[TxOutput(value=5400, token_data=0, script='dqkUutgaVG8W5OnzgAEVUqB4XgmDgm2IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HPZ4x7a2NXdrMa5ksPfeGMZmjhJHTjDZ9Q', timelock=None)), TxOutput(value=1000, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650', spent_outputs=[SpentOutput(index=0, tx_ids=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6'])], conflict_with=[], voided_by=[], received_by=[], children=['d2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9'], twins=[], accumulated_weight=18.656776158409354, score=0.0, first_block='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=38, timestamp=1578879091.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', nonce=0, timestamp=1578879090, version=0, weight=8.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUTisHvpM4sDeINzxF5auK/8bP6UaIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HDeSe6qKqjSLwtnjLBV84NddtZQyNb9HUU', timelock=None))], parents=['f349fc0f570a636a440ed3853cc533faa2c4616160e1d9eb6f5d656a90da30fb', 'd2bd5f83fcbfa5dee2b602ddc18ebd4f7714e1ecf928824f862efb0559dcb4d6', '5453759e15a6413a06390868cbb56509704c6f3f7d25f443556d8d6b2dacc650'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='7c7449a44a6adf26fb9b68f8c2b7751905c788b417946c43b8a999d0b66f76d9', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=8.0, score=19.576585413276128, first_block=None, height=12, validation='full'), aux_pow=None), group_id=None), latest_event_id=38, stream_id=stream_id) # noqa: E501 ] @@ -158,7 +159,7 @@ def test_reorg(self): responses = self._get_success_responses() expected = [ - # # LOAD_STATED + # LOAD_STATED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=0, timestamp=1578878880.0, type=EventType.LOAD_STARTED, data=EmptyData(), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for each genesis (1 block and 2 txs) EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=1, timestamp=1578878880.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', nonce=0, timestamp=1572636343, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=100000000000, token_data=0, script='dqkU/QUFm2AGJJVDuC82h2oXxz/SJnuIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HVayMofEDh4XGsaQJeRJKhutYxYodYNop6', timelock=None))], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 @@ -167,27 +168,27 @@ def test_reorg(self): # LOAD_FINISHED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=4, timestamp=1578878880.0, type=EventType.LOAD_FINISHED, data=EmptyData(), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=5, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=6, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=7, timestamp=1578878940.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], twins=[], accumulated_weight=2.0, score=2.0, first_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager1 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=8, timestamp=1578878940.25, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 # Also one VERTEX_METADATA_CHANGED for the previous block, voiding it EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=9, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=10, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=11, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', nonce=0, timestamp=1578878940, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUPXOcGnrN0ZB2WrnPVcjdCCcacL+IrA==', decoded=DecodedTxOutput(type='P2PKH', address='HC846khX278aM1utqAgPzkKAxBTfftaRDm', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', spent_outputs=[], conflict_with=[], voided_by=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=12, timestamp=1578879064.0, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], twins=[], accumulated_weight=2.0, score=2.0, first_block=None, height=0, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=13, timestamp=1578879064.0, type=EventType.NEW_VERTEX_ACCEPTED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533'], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=None), latest_event_id=20, stream_id=stream_id), # noqa: E501 # REORG_STARTED caused by a new block from manager2 (below) EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=14, timestamp=1578879064.25, type=EventType.REORG_STARTED, data=ReorgData(reorg_size=1, previous_best_block='82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', new_best_block='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', common_block='339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792'), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One VERTEX_METADATA_CHANGED for a new block (below), and one VERTEX_METADATA_CHANGED for each genesis tx (2), adding the new block as their child # noqa: E501 # Also one VERTEX_METADATA_CHANGED for the previous block, un-voiding it as it's now part of the best blockchain # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=15, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=16, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', nonce=0, timestamp=1578879000, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUfBo1MGBHkHtXDktO+BxtBdh5T5GIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HHqKa5Y6viZ8fkH2bd1qQBdsZnrtsmruqS', timelock=None))], parents=['339f47da87435842b0b1b528ecd9eac2495ce983b3e9c923a37e1befbe12c792', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=4.0, first_block=None, height=1, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=17, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', nonce=2, timestamp=1572636345, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 - EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', nonce=0, timestamp=1578879001, version=0, weight=2.0, inputs=[], outputs=[TxOutput(value=6400, token_data=0, script='dqkUgQrqLefPfPVpkXlfvvAp943epyOIrA==', decoded=DecodedTxOutput(type='P2PKH', address='HJHSdTickduA1MF9PTbzBQi6Z7stNAzwAu', timelock=None))], parents=['1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', '33e14cb555a96967841dcbe0f95e9eab5810481d01de8f4f73afb8cce365e869'], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=[], twins=[], accumulated_weight=2.0, score=4.321928094887363, first_block=None, height=2, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 + EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=18, timestamp=1578879064.25, type=EventType.VERTEX_METADATA_CHANGED, data=TxData(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', nonce=6, timestamp=1572636344, version=1, weight=2.0, inputs=[], outputs=[], parents=[], tokens=[], token_name=None, token_symbol=None, metadata=TxMetadata(hash='16ba3dbe424c443e571b00840ca54b9ff4cff467e10b6a15536e718e2008f952', spent_outputs=[], conflict_with=[], voided_by=[], received_by=[], children=['82afedcd590f7ad34d09475fc1dfd00e5a0f8ad6b70508ca4659351709c90f9a', '1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', '38e7f91420ae78ae01707f80c29abe692beebf9d5575cc7c9248e9bdc78169c1'], twins=[], accumulated_weight=2.0, score=2.0, first_block='1204b8c30f0236ae6f1841d0c4805a47089c4d5e3ccd0dcab8aa65f0e4991533', height=0, validation='full'), aux_pow=None), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 # REORG_FINISHED EventResponse(type='EVENT', event=BaseEvent(peer_id=self.peer_id, id=19, timestamp=1578879064.25, type=EventType.REORG_FINISHED, data=EmptyData(), group_id=0), latest_event_id=20, stream_id=stream_id), # noqa: E501 # One NEW_VERTEX_ACCEPTED for a new block from manager2 From 1360614b41d8ece6649e8901c9f96a4a0abe161c Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Tue, 19 Sep 2023 23:19:25 -0300 Subject: [PATCH 15/26] fix(feature-activation): add signal bits to minimally valid block --- hathor/mining/block_template.py | 5 +++-- tests/tx/test_mining.py | 37 ++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/hathor/mining/block_template.py b/hathor/mining/block_template.py index 6a77c274e..54e690d95 100644 --- a/hathor/mining/block_template.py +++ b/hathor/mining/block_template.py @@ -36,7 +36,7 @@ class BlockTemplate(NamedTuple): score: float # metadata signal_bits: int # signal bits for blocks generated from this template - def generate_minimaly_valid_block(self) -> BaseTransaction: + def generate_minimally_valid_block(self) -> BaseTransaction: """ Generates a block, without any extra information that is valid for this template. No random choices.""" from hathor.transaction import TxOutput, TxVersion return TxVersion(min(self.versions)).get_cls()( @@ -44,6 +44,7 @@ def generate_minimaly_valid_block(self) -> BaseTransaction: parents=self.parents[:] + sorted(self.parents_any)[:(3 - len(self.parents))], outputs=[TxOutput(self.reward, b'')], weight=self.weight, + signal_bits=self.signal_bits, ) def generate_mining_block(self, rng: Random, merge_mined: bool = False, address: Optional[bytes] = None, @@ -83,7 +84,7 @@ def get_random_parents(self, rng: Random) -> tuple[bytes, bytes, bytes]: def to_dict(self) -> dict: return { - 'data': self.generate_minimaly_valid_block().get_struct_without_nonce().hex(), + 'data': self.generate_minimally_valid_block().get_struct_without_nonce().hex(), 'versions': sorted(self.versions), 'reward': self.reward, 'weight': self.weight, diff --git a/tests/tx/test_mining.py b/tests/tx/test_mining.py index 064739ad3..8524966dd 100644 --- a/tests/tx/test_mining.py +++ b/tests/tx/test_mining.py @@ -1,6 +1,8 @@ +from typing import Any + from hathor.conf import HathorSettings from hathor.mining import BlockTemplate -from hathor.transaction import sum_weights +from hathor.transaction import Block, sum_weights from hathor.transaction.storage import TransactionMemoryStorage from tests import unittest from tests.utils import add_new_blocks @@ -75,6 +77,39 @@ def test_regular_block_template(self) -> None: self.assertConsensusValid(manager) + def test_minimally_valid_block(self) -> None: + template = BlockTemplate( + versions={0}, + reward=6400, + weight=60, + timestamp_now=12345, + timestamp_min=12344, + timestamp_max=12346, + parents=[b'\x01', b'\x02', b'\x03'], + parents_any=[], + height=999, + score=100, + signal_bits=0b0101, + ) + block = template.generate_minimally_valid_block() + json = block.to_json() + expected: dict[str, Any] = dict( + data='', + hash=None, + inputs=[], + nonce=0, + outputs=[dict(script='', token_data=0, value=6400)], + parents=['01', '02', '03'], + signal_bits=0b0101, + timestamp=12344, + tokens=[], + version=0, + weight=60 + ) + + self.assertTrue(isinstance(block, Block)) + self.assertEqual(json, expected) + class SyncV1MiningTest(unittest.SyncV1Params, BaseMiningTest): __test__ = True From 28132004752c0b46dbb7321f506dbd3b86df3a02 Mon Sep 17 00:00:00 2001 From: Jan Segre Date: Thu, 28 Sep 2023 17:00:12 +0200 Subject: [PATCH 16/26] chore(ci): upload codecov results on Python 3.11 test job --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e35fced5..acc739962 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,12 +25,12 @@ jobs: 'os': ['ubuntu-22.04', 'macos-12', 'windows-2022'], 'include': [ # XXX: tests fail on these, not sure why, when running them individually each on passes, but not on `make tests` - # {'os': 'ubuntu-22.04', 'python': 'pypy-3.9'}, + # {'os': 'ubuntu-22.04', 'python': 'pypy-3.10'}, ], } # this is the fastest one: reduced_matrix = { - 'python': ['3.9'], + 'python': ['3.11'], 'os': ['ubuntu-22.04'], } github_repository = os.environ['GITHUB_REPOSITORY'] @@ -99,4 +99,4 @@ jobs: run: poetry run make tests - name: Upload coverage uses: codecov/codecov-action@v3 - if: matrix.python == 3.9 && startsWith(matrix.os, 'ubuntu') + if: matrix.python == 3.11 && startsWith(matrix.os, 'ubuntu') From 9a37b94c9ebc16cc930a0045bb0320b8a899bc89 Mon Sep 17 00:00:00 2001 From: Jan Segre Date: Thu, 28 Sep 2023 19:24:15 +0200 Subject: [PATCH 17/26] chore(ci): fix codecov main branch name --- .codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codecov.yml b/.codecov.yml index 6c772a419..a7ed5e802 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,5 +1,5 @@ codecov: - branch: dev + branch: master coverage: # https://docs.codecov.com/docs/coverage-configuration From c968aea2d65c4a98f21266726133dad7d7927225 Mon Sep 17 00:00:00 2001 From: Marcelo Salhab Brogliato Date: Fri, 22 Sep 2023 17:37:05 -0500 Subject: [PATCH 18/26] feat(p2p): run periodic bootstrap discovery --- hathor/builder/cli_builder.py | 6 ++-- hathor/conf/settings.py | 3 ++ hathor/manager.py | 36 +--------------------- hathor/p2p/manager.py | 56 +++++++++++++++++++++++++++++++---- 4 files changed, 57 insertions(+), 44 deletions(-) diff --git a/hathor/builder/cli_builder.py b/hathor/builder/cli_builder.py index 1f2e6f7b1..cbf5b6857 100644 --- a/hathor/builder/cli_builder.py +++ b/hathor/builder/cli_builder.py @@ -262,10 +262,10 @@ def create_manager(self, reactor: Reactor) -> HathorManager: dns_hosts.extend(self._args.dns) if dns_hosts: - self.manager.add_peer_discovery(DNSPeerDiscovery(dns_hosts)) + p2p_manager.add_peer_discovery(DNSPeerDiscovery(dns_hosts)) if self._args.bootstrap: - self.manager.add_peer_discovery(BootstrapPeerDiscovery(self._args.bootstrap)) + p2p_manager.add_peer_discovery(BootstrapPeerDiscovery(self._args.bootstrap)) if self._args.test_mode_tx_weight: _set_test_mode(TestMode.TEST_TX_WEIGHT) @@ -281,7 +281,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager: self.log.warn('--memory-indexes is implied for memory storage or JSON storage') for description in self._args.listen: - self.manager.add_listen_address(description) + p2p_manager.add_listen_address(description) if self._args.peer_id_blacklist: self.log.info('with peer id blacklist', blacklist=self._args.peer_id_blacklist) diff --git a/hathor/conf/settings.py b/hathor/conf/settings.py index 884c4e8e0..f7af7faaa 100644 --- a/hathor/conf/settings.py +++ b/hathor/conf/settings.py @@ -392,6 +392,9 @@ def MAXIMUM_NUMBER_OF_HALVINGS(self) -> int: # Time to update the peers that are running sync. SYNC_UPDATE_INTERVAL: int = 10 * 60 # seconds + # Interval to re-run peer discovery. + PEER_DISCOVERY_INTERVAL: int = 5 * 60 # seconds + # All settings related to Feature Activation FEATURE_ACTIVATION: FeatureActivationSettings = FeatureActivationSettings() diff --git a/hathor/manager.py b/hathor/manager.py index 99f46cc5e..7ae37d01a 100644 --- a/hathor/manager.py +++ b/hathor/manager.py @@ -44,7 +44,6 @@ from hathor.feature_activation.feature_service import FeatureService from hathor.mining import BlockTemplate, BlockTemplates from hathor.p2p.manager import ConnectionsManager -from hathor.p2p.peer_discovery import PeerDiscovery from hathor.p2p.peer_id import PeerId from hathor.p2p.protocol import HathorProtocol from hathor.profiler import get_cpu_profiler @@ -183,8 +182,6 @@ def __init__(self, self.consensus_algorithm = consensus_algorithm - self.peer_discoveries: list[PeerDiscovery] = [] - self.connections = p2p_manager self.metrics = Metrics( @@ -209,9 +206,6 @@ def __init__(self, # Thread pool used to resolve pow when sending tokens self.pow_thread_pool = ThreadPool(minthreads=0, maxthreads=settings.MAX_POW_THREADS, name='Pow thread pool') - # List of addresses to listen for new connections (eg: [tcp:8000]) - self.listen_addresses: list[str] = [] - # Full verification execute all validations for transactions and blocks when initializing the node # Can be activated on the command line with --full-verification self._full_verification = full_verification @@ -277,7 +271,6 @@ def start(self) -> None: self.state = self.NodeState.INITIALIZING self.pubsub.publish(HathorEvents.MANAGER_ON_START) self._event_manager.load_started() - self.connections.start() self.pow_thread_pool.start() # Disable get transaction lock when initializing components @@ -300,10 +293,7 @@ def start(self) -> None: # Metric starts to capture data self.metrics.start() - for description in self.listen_addresses: - self.listen(description) - - self.do_discovery() + self.connections.start() self.start_time = time.time() @@ -353,13 +343,6 @@ def stop(self) -> Deferred: return defer.DeferredList(waits) - def do_discovery(self) -> None: - """ - Do a discovery and connect on all discovery strategies. - """ - for peer_discovery in self.peer_discoveries: - peer_discovery.discover_and_connect(self.connections.connect_to) - def start_profiler(self, *, reset: bool = False) -> None: """ Start profiler. It can be activated from a web resource, as well. @@ -695,12 +678,6 @@ def _sync_v2_resume_validations(self) -> None: self.sync_v2_step_validations(depended_final_txs, quiet=True) self.log.debug('pending validations finished') - def add_listen_address(self, addr: str) -> None: - self.listen_addresses.append(addr) - - def add_peer_discovery(self, peer_discovery: PeerDiscovery) -> None: - self.peer_discoveries.append(peer_discovery) - def get_new_tx_parents(self, timestamp: Optional[float] = None) -> list[VertexId]: """Select which transactions will be confirmed by a new transaction. @@ -1141,17 +1118,6 @@ def _log_if_feature_is_active(self, block: Block, feature: Feature) -> None: if self._feature_service.is_feature_active(block=block, feature=feature): self.log.info('Feature is ACTIVE for block', feature=feature.value, block_height=block.get_height()) - def listen(self, description: str, use_ssl: Optional[bool] = None) -> None: - endpoint = self.connections.listen(description, use_ssl) - # XXX: endpoint: IStreamServerEndpoint does not intrinsically have a port, but in practice all concrete cases - # that we have will have a _port attribute - port = getattr(endpoint, '_port', None) - - if self.hostname: - proto, _, _ = description.partition(':') - address = '{}://{}:{}'.format(proto, self.hostname, port) - self.my_peer.entrypoints.append(address) - def has_sync_version_capability(self) -> bool: return settings.CAPABILITY_SYNC_VERSION in self.capabilities diff --git a/hathor/p2p/manager.py b/hathor/p2p/manager.py index 007851ff6..4e6639185 100644 --- a/hathor/p2p/manager.py +++ b/hathor/p2p/manager.py @@ -24,6 +24,7 @@ from hathor.conf import HathorSettings from hathor.p2p.netfilter.factory import NetfilterFactory +from hathor.p2p.peer_discovery import PeerDiscovery from hathor.p2p.peer_id import PeerId from hathor.p2p.peer_storage import PeerStorage from hathor.p2p.protocol import HathorProtocol @@ -73,6 +74,7 @@ class ConnectionsManager: """ MAX_ENABLED_SYNC = settings.MAX_ENABLED_SYNC SYNC_UPDATE_INTERVAL = settings.SYNC_UPDATE_INTERVAL + PEER_DISCOVERY_INTERVAL = settings.PEER_DISCOVERY_INTERVAL class GlobalRateLimiter: SEND_TIPS = 'NodeSyncTimestamp.send_tips' @@ -114,6 +116,12 @@ def __init__(self, self.network = network + # List of addresses to listen for new connections (eg: [tcp:8000]) + self.listen_addresses: list[str] = [] + + # List of peer discovery methods. + self.peer_discoveries: list[PeerDiscovery] = [] + # Options self.localhost_only = False @@ -179,6 +187,9 @@ def __init__(self, self.enable_sync_v1_1 = enable_sync_v1_1 self.enable_sync_v2 = enable_sync_v2 + # Timestamp when the last discovery ran + self._last_discovery: float = 0. + # sync-manager factories self._sync_factories = {} if enable_sync_v1: @@ -198,6 +209,21 @@ def set_manager(self, manager: 'HathorManager') -> None: indexes.enable_deps_index() indexes.enable_mempool_index() + def add_listen_address(self, addr: str) -> None: + """Add address to listen for incoming connections.""" + self.listen_addresses.append(addr) + + def add_peer_discovery(self, peer_discovery: PeerDiscovery) -> None: + """Add a peer discovery method.""" + self.peer_discoveries.append(peer_discovery) + + def do_discovery(self) -> None: + """ + Do a discovery and connect on all discovery strategies. + """ + for peer_discovery in self.peer_discoveries: + peer_discovery.discover_and_connect(self.connect_to) + def disable_rate_limiter(self) -> None: """Disable global rate limiter.""" self.rate_limiter.unset_limit(self.GlobalRateLimiter.SEND_TIPS) @@ -213,9 +239,15 @@ def enable_rate_limiter(self, max_hits: int = 16, window_seconds: float = 1) -> def start(self) -> None: self.lc_reconnect.start(5, now=False) self.lc_sync_update.start(self.lc_sync_update_interval, now=False) + if settings.ENABLE_PEER_WHITELIST: self._start_whitelist_reconnect() + for description in self.listen_addresses: + self.listen(description) + + self.do_discovery() + def _start_whitelist_reconnect(self) -> None: # The deferred returned by the LoopingCall start method # executes when the looping call stops running @@ -424,7 +456,7 @@ def on_receive_peer(self, peer: PeerId, origin: Optional[ReadyState] = None) -> if peer.id == self.my_peer.id: return peer = self.received_peer_storage.add_or_merge(peer) - self.connect_to_if_not_connected(peer, 0) + self.connect_to_if_not_connected(peer, int(self.reactor.seconds())) def reconnect_to_all(self) -> None: """ It is called by the `lc_reconnect` timer and tries to connect to all known @@ -434,13 +466,14 @@ def reconnect_to_all(self) -> None: """ # when we have no connected peers left, run the discovery process again assert self.manager is not None - if len(self.connected_peers) < 1: - self.manager.do_discovery() - now = int(self.reactor.seconds()) + now = self.reactor.seconds() + if now - self._last_discovery >= self.PEER_DISCOVERY_INTERVAL: + self._last_discovery = now + self.do_discovery() # We need to use list() here because the dict might change inside connect_to_if_not_connected # when the peer is disconnected and without entrypoint for peer in list(self.peer_storage.values()): - self.connect_to_if_not_connected(peer, now) + self.connect_to_if_not_connected(peer, int(now)) def update_whitelist(self) -> Deferred[None]: from twisted.web.client import Agent, readBody @@ -580,7 +613,7 @@ def connect_to(self, description: str, peer: Optional[PeerId] = None, use_ssl: O ) def listen(self, description: str, use_ssl: Optional[bool] = None) -> IStreamServerEndpoint: - """ Start to listen to new connection according to the description. + """ Start to listen for new connection according to the description. If `ssl` is True, then the connection will be wraped by a TLS. @@ -607,6 +640,17 @@ def listen(self, description: str, use_ssl: Optional[bool] = None) -> IStreamSer self.log.info('listen on', endpoint=description) endpoint.listen(factory) + + # XXX: endpoint: IStreamServerEndpoint does not intrinsically have a port, but in practice all concrete cases + # that we have will have a _port attribute + port = getattr(endpoint, '_port', None) + assert self.manager is not None + if self.manager.hostname and port is not None: + proto, _, _ = description.partition(':') + address = '{}://{}:{}'.format(proto, self.manager.hostname, port) + assert self.manager.my_peer is not None + self.manager.my_peer.entrypoints.append(address) + return endpoint def get_connection_to_drop(self, protocol: HathorProtocol) -> HathorProtocol: From 32da24dd339c1440aca24ee3018aa23abc866d3e Mon Sep 17 00:00:00 2001 From: Marcelo Salhab Brogliato Date: Thu, 21 Sep 2023 17:53:36 -0500 Subject: [PATCH 19/26] feat(wallet): Add BaseWallet.get_balance_per_address() method --- hathor/types.py | 1 + hathor/wallet/base_wallet.py | 8 ++++++++ tests/wallet/test_balance_update.py | 3 +++ 3 files changed, 12 insertions(+) diff --git a/hathor/types.py b/hathor/types.py index 07c42194a..f035a8c80 100644 --- a/hathor/types.py +++ b/hathor/types.py @@ -17,6 +17,7 @@ VertexId = bytes # NewType('TxId', bytes) Address = bytes # NewType('Address', bytes) +AddressB58 = str TxOutputScript = bytes # NewType('TxOutputScript', bytes) Timestamp = int # NewType('Timestamp', int) TokenUid = VertexId # NewType('TokenUid', VertexId) diff --git a/hathor/wallet/base_wallet.py b/hathor/wallet/base_wallet.py index 63c7287c9..913c13bc7 100644 --- a/hathor/wallet/base_wallet.py +++ b/hathor/wallet/base_wallet.py @@ -32,6 +32,7 @@ from hathor.transaction.scripts import P2PKH, create_output_script, parse_address_script from hathor.transaction.storage import TransactionStorage from hathor.transaction.transaction import Transaction +from hathor.types import AddressB58, Amount, TokenUid from hathor.util import Reactor from hathor.wallet.exceptions import InputDuplicated, InsufficientFunds, PrivateKeyNotFound @@ -135,6 +136,13 @@ def __init__(self, directory: str = './', pubsub: Optional[PubSubManager] = None def _manually_initialize(self) -> None: pass + def get_balance_per_address(self, token_uid: TokenUid) -> dict[AddressB58, Amount]: + """Return balance per address for a given token. This method ignores locks.""" + balances: defaultdict[AddressB58, Amount] = defaultdict(Amount) + for utxo_info, unspent_tx in self.unspent_txs[token_uid].items(): + balances[unspent_tx.address] += unspent_tx.value + return dict(balances) + def start(self) -> None: """ Start the pubsub subscription if wallet has a pubsub """ diff --git a/tests/wallet/test_balance_update.py b/tests/wallet/test_balance_update.py index ab2260866..15aad3e6b 100644 --- a/tests/wallet/test_balance_update.py +++ b/tests/wallet/test_balance_update.py @@ -436,6 +436,9 @@ def test_tokens_balance(self): # hathor balance remains the same self.assertEqual(self.manager.wallet.balance[settings.HATHOR_TOKEN_UID], hathor_balance) + balances_per_address = self.manager.wallet.get_balance_per_address(settings.HATHOR_TOKEN_UID) + self.assertEqual(hathor_balance.available, sum(x for x in balances_per_address.values())) + class SyncV1HathorSyncMethodsTestCase(unittest.SyncV1Params, BaseHathorSyncMethodsTestCase): __test__ = True From 85a3bfc15bb2c784ce69ff72a0b44c06ecaab93a Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Mon, 25 Sep 2023 19:06:12 -0300 Subject: [PATCH 20/26] refactor(settings): change HathorManager to use injected settings --- hathor/builder/builder.py | 1 + hathor/builder/cli_builder.py | 1 + hathor/manager.py | 69 ++++++++++++++++----------- tests/p2p/test_get_best_blockchain.py | 4 +- 4 files changed, 45 insertions(+), 30 deletions(-) diff --git a/hathor/builder/builder.py b/hathor/builder/builder.py index 3a4631476..ecb2bd02c 100644 --- a/hathor/builder/builder.py +++ b/hathor/builder/builder.py @@ -181,6 +181,7 @@ def build(self) -> BuildArtifacts: manager = HathorManager( reactor, + settings=settings, network=self._network, pubsub=pubsub, consensus_algorithm=consensus_algorithm, diff --git a/hathor/builder/cli_builder.py b/hathor/builder/cli_builder.py index cbf5b6857..b259c7c98 100644 --- a/hathor/builder/cli_builder.py +++ b/hathor/builder/cli_builder.py @@ -220,6 +220,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager: self.manager = HathorManager( reactor, + settings=settings, network=network, hostname=hostname, pubsub=pubsub, diff --git a/hathor/manager.py b/hathor/manager.py index 7ae37d01a..630c1b54c 100644 --- a/hathor/manager.py +++ b/hathor/manager.py @@ -27,7 +27,7 @@ from hathor import daa from hathor.checkpoint import Checkpoint -from hathor.conf import HathorSettings +from hathor.conf.settings import HathorSettings from hathor.consensus import ConsensusAlgorithm from hathor.event.event_manager import EventManager from hathor.exception import ( @@ -59,18 +59,10 @@ from hathor.verification.verification_service import VerificationService from hathor.wallet import BaseWallet -settings = HathorSettings() logger = get_logger() cpu = get_cpu_profiler() -DEFAULT_CAPABILITIES = [ - settings.CAPABILITY_WHITELIST, - settings.CAPABILITY_SYNC_VERSION, - settings.CAPABILITY_GET_BEST_BLOCKCHAIN -] - - class HathorManager: """ HathorManager manages the node with the help of other specialized classes. @@ -94,6 +86,7 @@ class UnhealthinessReason(str, Enum): def __init__(self, reactor: Reactor, *, + settings: HathorSettings, pubsub: PubSubManager, consensus_algorithm: ConsensusAlgorithm, peer_id: PeerId, @@ -129,6 +122,7 @@ def __init__(self, 'Either enable it, or use the reset-event-queue CLI command to remove all event-related data' ) + self._settings = settings self._cmd_path: Optional[str] = None self.log = logger.new() @@ -217,7 +211,7 @@ def __init__(self, if capabilities is not None: self.capabilities = capabilities else: - self.capabilities = DEFAULT_CAPABILITIES + self.capabilities = self.get_default_capabilities() # This is included in some logs to provide more context self.environment_info = environment_info @@ -227,6 +221,14 @@ def __init__(self, self.lc_check_sync_state.clock = self.reactor self.lc_check_sync_state_interval = self.CHECK_SYNC_STATE_INTERVAL + def get_default_capabilities(self) -> list[str]: + """Return the default capabilities for this manager.""" + return [ + self._settings.CAPABILITY_WHITELIST, + self._settings.CAPABILITY_SYNC_VERSION, + self._settings.CAPABILITY_GET_BEST_BLOCKCHAIN + ] + def start(self) -> None: """ A factory must be started only once. And it is usually automatically started. """ @@ -426,7 +428,7 @@ def _initialize_components_full_verification(self) -> None: # It's safe to skip block weight verification during initialization because # we trust the difficulty stored in metadata skip_block_weight_verification = True - if block_count % settings.VERIFY_WEIGHT_EVERY_N_BLOCKS == 0: + if block_count % self._settings.VERIFY_WEIGHT_EVERY_N_BLOCKS == 0: skip_block_weight_verification = False try: @@ -611,14 +613,14 @@ def _verify_soft_voided_txs(self) -> None: soft_voided_meta = soft_voided_tx.get_metadata() voided_set = soft_voided_meta.voided_by or set() # If the tx is not marked as soft voided, then we can't continue the initialization - if settings.SOFT_VOIDED_ID not in voided_set: + if self._settings.SOFT_VOIDED_ID not in voided_set: self.log.error( 'Error initializing node. Your database is not compatible with the current version of the' ' full node. You must use the latest available snapshot or sync from the beginning.' ) sys.exit(-1) - assert {soft_voided_id, settings.SOFT_VOIDED_ID}.issubset(voided_set) + assert {soft_voided_id, self._settings.SOFT_VOIDED_ID}.issubset(voided_set) def _verify_checkpoints(self) -> None: """ Method to verify if all checkpoints that exist in the database have the correct hash and are winners. @@ -751,7 +753,7 @@ def make_block_template(self, parent_block_hash: VertexId, timestamp: Optional[i """ parent_block = self.tx_storage.get_transaction(parent_block_hash) assert isinstance(parent_block, Block) - parent_txs = self.generate_parent_txs(parent_block.timestamp + settings.MAX_DISTANCE_BETWEEN_BLOCKS) + parent_txs = self.generate_parent_txs(parent_block.timestamp + self._settings.MAX_DISTANCE_BETWEEN_BLOCKS) if timestamp is None: current_timestamp = int(max(self.tx_storage.latest_timestamp, self.reactor.seconds())) else: @@ -787,7 +789,7 @@ def _make_block_template(self, parent_block: Block, parent_txs: 'ParentTxs', cur timestamp_abs_min = parent_block.timestamp + 1 # and absolute maximum limited by max time between blocks if not parent_block.is_genesis: - timestamp_abs_max = parent_block.timestamp + settings.MAX_DISTANCE_BETWEEN_BLOCKS - 1 + timestamp_abs_max = parent_block.timestamp + self._settings.MAX_DISTANCE_BETWEEN_BLOCKS - 1 else: timestamp_abs_max = 0xffffffff assert timestamp_abs_max > timestamp_abs_min @@ -796,12 +798,12 @@ def _make_block_template(self, parent_block: Block, parent_txs: 'ParentTxs', cur timestamp_min = max(timestamp_abs_min, parent_txs.max_timestamp + 1) assert timestamp_min <= timestamp_abs_max # when we have weight decay, the max timestamp will be when the next decay happens - if with_weight_decay and settings.WEIGHT_DECAY_ENABLED: + if with_weight_decay and self._settings.WEIGHT_DECAY_ENABLED: # we either have passed the first decay or not, the range will vary depending on that - if timestamp_min > timestamp_abs_min + settings.WEIGHT_DECAY_ACTIVATE_DISTANCE: - timestamp_max_decay = timestamp_min + settings.WEIGHT_DECAY_WINDOW_SIZE + if timestamp_min > timestamp_abs_min + self._settings.WEIGHT_DECAY_ACTIVATE_DISTANCE: + timestamp_max_decay = timestamp_min + self._settings.WEIGHT_DECAY_WINDOW_SIZE else: - timestamp_max_decay = timestamp_abs_min + settings.WEIGHT_DECAY_ACTIVATE_DISTANCE + timestamp_max_decay = timestamp_abs_min + self._settings.WEIGHT_DECAY_ACTIVATE_DISTANCE timestamp_max = min(timestamp_abs_max, timestamp_max_decay) else: timestamp_max = timestamp_abs_max @@ -810,7 +812,10 @@ def _make_block_template(self, parent_block: Block, parent_txs: 'ParentTxs', cur # this is the min weight to cause an increase of twice the WEIGHT_TOL, we make sure to generate a template with # at least this weight (note that the user of the API can set its own weight, the block sumit API will also # protect agains a weight that is too small but using WEIGHT_TOL instead of 2*WEIGHT_TOL) - min_significant_weight = calculate_min_significant_weight(parent_block_metadata.score, 2 * settings.WEIGHT_TOL) + min_significant_weight = calculate_min_significant_weight( + parent_block_metadata.score, + 2 * self._settings.WEIGHT_TOL + ) weight = max(daa.calculate_next_weight(parent_block, timestamp), min_significant_weight) height = parent_block.get_height() + 1 parents = [parent_block.hash] + parent_txs.must_include @@ -875,15 +880,21 @@ def submit_block(self, blk: Block, fails_silently: bool = True) -> bool: parent_block = self.tx_storage.get_transaction(parent_hash) parent_block_metadata = parent_block.get_metadata() # this is the smallest weight that won't cause the score to increase, anything equal or smaller is bad - min_insignificant_weight = calculate_min_significant_weight(parent_block_metadata.score, settings.WEIGHT_TOL) + min_insignificant_weight = calculate_min_significant_weight( + parent_block_metadata.score, + self._settings.WEIGHT_TOL + ) if blk.weight <= min_insignificant_weight: self.log.warn('submit_block(): insignificant weight? accepted anyway', blk=blk.hash_hex, weight=blk.weight) return self.propagate_tx(blk, fails_silently=fails_silently) def push_tx(self, tx: Transaction, allow_non_standard_script: bool = False, - max_output_script_size: int = settings.PUSHTX_MAX_OUTPUT_SCRIPT_SIZE) -> None: + max_output_script_size: int | None = None) -> None: """Used by all APIs that accept a new transaction (like push_tx) """ + if max_output_script_size is None: + max_output_script_size = self._settings.PUSHTX_MAX_OUTPUT_SCRIPT_SIZE + is_double_spending = tx.is_double_spending() if is_double_spending: raise DoubleSpendingError('Invalid transaction. At least one of your inputs has already been spent.') @@ -945,7 +956,7 @@ def on_new_tx(self, tx: BaseTransaction, *, conn: Optional[HathorProtocol] = Non self.tx_storage.compare_bytes_with_local_tx(tx) already_exists = True - if tx.timestamp - self.reactor.seconds() > settings.MAX_FUTURE_TIMESTAMP_ALLOWED: + if tx.timestamp - self.reactor.seconds() > self._settings.MAX_FUTURE_TIMESTAMP_ALLOWED: if not fails_silently: raise InvalidNewTransaction('Ignoring transaction in the future {} (timestamp={})'.format( tx.hash_hex, tx.timestamp)) @@ -1094,7 +1105,7 @@ def tx_fully_validated(self, tx: BaseTransaction, *, quiet: bool) -> None: def _log_feature_states(self, vertex: BaseTransaction) -> None: """Log features states for a block. Used as part of the Feature Activation Phased Testing.""" - if not settings.FEATURE_ACTIVATION.enable_usage or not isinstance(vertex, Block): + if not self._settings.FEATURE_ACTIVATION.enable_usage or not isinstance(vertex, Block): return feature_descriptions = self._feature_service.get_bits_description(block=vertex) @@ -1119,10 +1130,10 @@ def _log_if_feature_is_active(self, block: Block, feature: Feature) -> None: self.log.info('Feature is ACTIVE for block', feature=feature.value, block_height=block.get_height()) def has_sync_version_capability(self) -> bool: - return settings.CAPABILITY_SYNC_VERSION in self.capabilities + return self._settings.CAPABILITY_SYNC_VERSION in self.capabilities def add_peer_to_whitelist(self, peer_id): - if not settings.ENABLE_PEER_WHITELIST: + if not self._settings.ENABLE_PEER_WHITELIST: return if peer_id in self.peers_whitelist: @@ -1131,7 +1142,7 @@ def add_peer_to_whitelist(self, peer_id): self.peers_whitelist.append(peer_id) def remove_peer_from_whitelist_and_disconnect(self, peer_id: str) -> None: - if not settings.ENABLE_PEER_WHITELIST: + if not self._settings.ENABLE_PEER_WHITELIST: return if peer_id in self.peers_whitelist: @@ -1145,7 +1156,9 @@ def has_recent_activity(self) -> bool: # We use the avg time between blocks as a basis to know how much time we should use to consider the fullnode # as not synced. - maximum_timestamp_delta = settings.P2P_RECENT_ACTIVITY_THRESHOLD_MULTIPLIER * settings.AVG_TIME_BETWEEN_BLOCKS + maximum_timestamp_delta = ( + self._settings.P2P_RECENT_ACTIVITY_THRESHOLD_MULTIPLIER * self._settings.AVG_TIME_BETWEEN_BLOCKS + ) if current_timestamp - latest_blockchain_timestamp > maximum_timestamp_delta: return False diff --git a/tests/p2p/test_get_best_blockchain.py b/tests/p2p/test_get_best_blockchain.py index a37e4a742..806444be0 100644 --- a/tests/p2p/test_get_best_blockchain.py +++ b/tests/p2p/test_get_best_blockchain.py @@ -2,7 +2,6 @@ from hathor.conf import HathorSettings from hathor.indexes.height_index import HeightInfo -from hathor.manager import DEFAULT_CAPABILITIES from hathor.p2p.messages import ProtocolMessages from hathor.p2p.resources import StatusResource from hathor.p2p.states import ReadyState @@ -229,7 +228,8 @@ def test_node_without_get_best_blockchain_capability(self): protocol2 = connected_peers1[0] self.assertTrue(protocol2.capabilities.issuperset(set(cababilities_without_get_best_blockchain))) protocol1 = connected_peers2[0] - self.assertTrue(protocol1.capabilities.issuperset(set(DEFAULT_CAPABILITIES))) + default_capabilities = manager2.get_default_capabilities() + self.assertTrue(protocol1.capabilities.issuperset(set(default_capabilities))) # assert the peers don't engage in get_best_blockchain messages state2 = protocol2.state From 88ef27f578517bef388795c0f7dfcea022a78eb9 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Thu, 28 Sep 2023 19:48:44 -0300 Subject: [PATCH 21/26] refactor(settings): refactor genesis module --- hathor/builder/cli_builder.py | 5 +- hathor/conf/mainnet.py | 2 +- hathor/conf/mainnet.yml | 2 +- hathor/conf/settings.py | 15 ++++- hathor/conf/testnet.py | 2 +- hathor/conf/testnet.yml | 2 +- hathor/indexes/base_index.py | 2 + hathor/indexes/height_index.py | 11 +-- hathor/indexes/memory_height_index.py | 4 +- hathor/indexes/memory_info_index.py | 6 +- hathor/indexes/rocksdb_height_index.py | 5 +- hathor/p2p/utils.py | 5 +- hathor/simulator/simulator.py | 3 +- hathor/transaction/base_transaction.py | 2 +- hathor/transaction/genesis.py | 67 ++++--------------- .../storage/transaction_storage.py | 57 ++++++++++++++-- hathor/transaction/transaction_metadata.py | 14 ++-- .../invalid_byte_hathor_settings_fixture.yml | 2 +- ...valid_features_hathor_settings_fixture.yml | 2 +- .../missing_hathor_settings_fixture.yml | 2 +- .../valid_hathor_settings_fixture.yml | 2 +- tests/others/test_hathor_settings.py | 2 +- tests/p2p/test_split_brain.py | 3 +- tests/resources/wallet/test_thin_wallet.py | 4 +- tests/tx/test_block.py | 10 ++- tests/tx/test_indexes2.py | 2 +- tests/tx/test_mining.py | 2 +- tests/tx/test_stratum.py | 5 +- tests/tx/test_tx_storage.py | 16 +---- tests/unittest.py | 4 +- tests/utils.py | 4 +- 31 files changed, 138 insertions(+), 126 deletions(-) diff --git a/hathor/builder/cli_builder.py b/hathor/builder/cli_builder.py index b259c7c98..7dab5bdf5 100644 --- a/hathor/builder/cli_builder.py +++ b/hathor/builder/cli_builder.py @@ -31,7 +31,7 @@ from hathor.manager import HathorManager from hathor.p2p.manager import ConnectionsManager from hathor.p2p.peer_id import PeerId -from hathor.p2p.utils import discover_hostname +from hathor.p2p.utils import discover_hostname, get_genesis_short_hash from hathor.pubsub import PubSubManager from hathor.stratum import StratumFactory from hathor.util import Random, Reactor @@ -64,7 +64,6 @@ def create_manager(self, reactor: Reactor) -> HathorManager: from hathor.p2p.netfilter.utils import add_peer_id_blacklist from hathor.p2p.peer_discovery import BootstrapPeerDiscovery, DNSPeerDiscovery from hathor.storage import RocksDBStorage - from hathor.transaction import genesis from hathor.transaction.storage import ( TransactionCacheStorage, TransactionMemoryStorage, @@ -89,7 +88,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager: 'hathor-core v{hathor}', hathor=hathor.__version__, pid=os.getpid(), - genesis=genesis.GENESIS_HASH.hex()[:7], + genesis=get_genesis_short_hash(), my_peer_id=str(peer_id.id), python=python, platform=platform.platform(), diff --git a/hathor/conf/mainnet.py b/hathor/conf/mainnet.py index c7aa6fe90..f66691cf3 100644 --- a/hathor/conf/mainnet.py +++ b/hathor/conf/mainnet.py @@ -25,7 +25,7 @@ # Genesis stuff # output addr: HJB2yxxsHtudGGy3jmVeadwMfRi2zNCKKD GENESIS_OUTPUT_SCRIPT=bytes.fromhex('76a9147fd4ae0e4fb2d2854e76d359029d8078bb99649e88ac'), - GENESIS_TIMESTAMP=1578075305, + GENESIS_BLOCK_TIMESTAMP=1578075305, GENESIS_BLOCK_NONCE=2591358, GENESIS_BLOCK_HASH=bytes.fromhex('000006cb93385b8b87a545a1cbb6197e6caff600c12cc12fc54250d39c8088fc'), GENESIS_TX1_NONCE=7715, diff --git a/hathor/conf/mainnet.yml b/hathor/conf/mainnet.yml index 3a4fb38fe..baa6fa16a 100644 --- a/hathor/conf/mainnet.yml +++ b/hathor/conf/mainnet.yml @@ -8,7 +8,7 @@ WHITELIST_URL: https://hathor-public-files.s3.amazonaws.com/whitelist_peer_ids # Genesis stuff GENESIS_OUTPUT_SCRIPT: 76a9147fd4ae0e4fb2d2854e76d359029d8078bb99649e88ac -GENESIS_TIMESTAMP: 1578075305 +GENESIS_BLOCK_TIMESTAMP: 1578075305 GENESIS_BLOCK_NONCE: 2591358 GENESIS_BLOCK_HASH: 000006cb93385b8b87a545a1cbb6197e6caff600c12cc12fc54250d39c8088fc GENESIS_TX1_NONCE: 7715 diff --git a/hathor/conf/settings.py b/hathor/conf/settings.py index f7af7faaa..be31f0dd5 100644 --- a/hathor/conf/settings.py +++ b/hathor/conf/settings.py @@ -98,7 +98,20 @@ def MAXIMUM_NUMBER_OF_HALVINGS(self) -> int: GENESIS_OUTPUT_SCRIPT: bytes = bytes.fromhex('76a914a584cf48b161e4a49223ed220df30037ab740e0088ac') # Genesis timestamps, nonces and hashes - GENESIS_TIMESTAMP: int = 1572636343 # used as is for genesis_block, +1 for genesis_tx1 and +2 for genesis_tx2 + + # Timestamp used for the genesis block + GENESIS_BLOCK_TIMESTAMP: int = 1572636343 + + @property + def GENESIS_TX1_TIMESTAMP(self) -> int: + """Timestamp used for the first genesis transaction.""" + return self.GENESIS_BLOCK_TIMESTAMP + 1 + + @property + def GENESIS_TX2_TIMESTAMP(self) -> int: + """Timestamp used for the second genesis transaction.""" + return self.GENESIS_BLOCK_TIMESTAMP + 2 + GENESIS_BLOCK_NONCE: int = 3526202 GENESIS_BLOCK_HASH: bytes = bytes.fromhex('000007eb968a6cdf0499e2d033faf1e163e0dc9cf41876acad4d421836972038') GENESIS_TX1_NONCE: int = 12595 diff --git a/hathor/conf/testnet.py b/hathor/conf/testnet.py index b79ac6fe4..5f36d8b6b 100644 --- a/hathor/conf/testnet.py +++ b/hathor/conf/testnet.py @@ -25,7 +25,7 @@ BOOTSTRAP_DNS=['golf.testnet.hathor.network'], # Genesis stuff GENESIS_OUTPUT_SCRIPT=bytes.fromhex('76a914a584cf48b161e4a49223ed220df30037ab740e0088ac'), - GENESIS_TIMESTAMP=1577836800, + GENESIS_BLOCK_TIMESTAMP=1577836800, GENESIS_BLOCK_NONCE=826272, GENESIS_BLOCK_HASH=bytes.fromhex('0000033139d08176d1051fb3a272c3610457f0c7f686afbe0afe3d37f966db85'), GENESIS_TX1_NONCE=190, diff --git a/hathor/conf/testnet.yml b/hathor/conf/testnet.yml index 81eaf1c58..e2e1da6d3 100644 --- a/hathor/conf/testnet.yml +++ b/hathor/conf/testnet.yml @@ -6,7 +6,7 @@ BOOTSTRAP_DNS: # Genesis stuff GENESIS_OUTPUT_SCRIPT: 76a914a584cf48b161e4a49223ed220df30037ab740e0088ac -GENESIS_TIMESTAMP: 1577836800 +GENESIS_BLOCK_TIMESTAMP: 1577836800 GENESIS_BLOCK_NONCE: 826272 GENESIS_BLOCK_HASH: 0000033139d08176d1051fb3a272c3610457f0c7f686afbe0afe3d37f966db85 GENESIS_TX1_NONCE: 190 diff --git a/hathor/indexes/base_index.py b/hathor/indexes/base_index.py index 6d452f6d3..22a782313 100644 --- a/hathor/indexes/base_index.py +++ b/hathor/indexes/base_index.py @@ -17,6 +17,7 @@ from structlog import get_logger +from hathor.conf.get_settings import get_settings from hathor.indexes.scope import Scope from hathor.transaction.base_transaction import BaseTransaction @@ -33,6 +34,7 @@ class BaseIndex(ABC): created to generalize how we initialize indexes and keep track of which ones are up-to-date. """ def __init__(self) -> None: + self._settings = get_settings() self.log = logger.new() def init_start(self, indexes_manager: 'IndexesManager') -> None: diff --git a/hathor/indexes/height_index.py b/hathor/indexes/height_index.py index 167787e69..7bf91e181 100644 --- a/hathor/indexes/height_index.py +++ b/hathor/indexes/height_index.py @@ -18,7 +18,6 @@ from hathor.indexes.base_index import BaseIndex from hathor.indexes.scope import Scope from hathor.transaction import BaseTransaction, Block -from hathor.transaction.genesis import BLOCK_GENESIS from hathor.types import VertexId from hathor.util import not_none @@ -41,9 +40,6 @@ class HeightInfo(NamedTuple): id: VertexId -BLOCK_GENESIS_ENTRY: IndexEntry = IndexEntry(not_none(BLOCK_GENESIS.hash), BLOCK_GENESIS.timestamp) - - class _AddToIndexItem(NamedTuple): height: int hash: bytes @@ -54,6 +50,13 @@ class HeightIndex(BaseIndex): """Store the block hash for each given height """ + def get_genesis_block_entry(self) -> IndexEntry: + """Return the index entry for the genesis block.""" + return IndexEntry( + self._settings.GENESIS_BLOCK_HASH, + self._settings.GENESIS_BLOCK_TIMESTAMP + ) + def get_scope(self) -> Scope: return SCOPE diff --git a/hathor/indexes/memory_height_index.py b/hathor/indexes/memory_height_index.py index db1ec4cc9..50bf03004 100644 --- a/hathor/indexes/memory_height_index.py +++ b/hathor/indexes/memory_height_index.py @@ -14,7 +14,7 @@ from typing import Optional -from hathor.indexes.height_index import BLOCK_GENESIS_ENTRY, HeightIndex, HeightInfo, IndexEntry +from hathor.indexes.height_index import HeightIndex, HeightInfo, IndexEntry class MemoryHeightIndex(HeightIndex): @@ -31,7 +31,7 @@ def get_db_name(self) -> Optional[str]: return None def force_clear(self) -> None: - self._index = [BLOCK_GENESIS_ENTRY] + self._index = [self.get_genesis_block_entry()] def _add(self, height: int, block_hash: bytes, timestamp: int, *, can_reorg: bool) -> None: if len(self._index) < height: diff --git a/hathor/indexes/memory_info_index.py b/hathor/indexes/memory_info_index.py index cddd73ff6..656cc7972 100644 --- a/hathor/indexes/memory_info_index.py +++ b/hathor/indexes/memory_info_index.py @@ -23,6 +23,7 @@ class MemoryInfoIndex(InfoIndex): def __init__(self): + super().__init__() self._block_count = 0 self._tx_count = 0 self._first_timestamp = 0 @@ -35,11 +36,10 @@ def get_db_name(self) -> Optional[str]: return None def force_clear(self) -> None: - from hathor.transaction.genesis import BLOCK_GENESIS, TX_GENESIS2 self._block_count = 1 self._tx_count = 2 - self._first_timestamp = BLOCK_GENESIS.timestamp - self._latest_timestamp = TX_GENESIS2.timestamp + self._first_timestamp = self._settings.GENESIS_BLOCK_TIMESTAMP + self._latest_timestamp = self._settings.GENESIS_TX2_TIMESTAMP def update_timestamps(self, tx: BaseTransaction) -> None: if tx.is_genesis: diff --git a/hathor/indexes/rocksdb_height_index.py b/hathor/indexes/rocksdb_height_index.py index 512606de8..562bbf43c 100644 --- a/hathor/indexes/rocksdb_height_index.py +++ b/hathor/indexes/rocksdb_height_index.py @@ -16,7 +16,7 @@ from structlog import get_logger -from hathor.indexes.height_index import BLOCK_GENESIS_ENTRY, HeightIndex, HeightInfo, IndexEntry +from hathor.indexes.height_index import HeightIndex, HeightInfo, IndexEntry from hathor.indexes.rocksdb_utils import RocksDBIndexUtils if TYPE_CHECKING: # pragma: no cover @@ -44,6 +44,7 @@ class RocksDBHeightIndex(HeightIndex, RocksDBIndexUtils): def __init__(self, db: 'rocksdb.DB', *, cf_name: Optional[bytes] = None) -> None: self.log = logger.new() + HeightIndex.__init__(self) RocksDBIndexUtils.__init__(self, db, cf_name or _CF_NAME_HEIGHT_INDEX) def get_db_name(self) -> Optional[str]: @@ -56,7 +57,7 @@ def force_clear(self) -> None: def _init_db(self) -> None: """ Initialize the database with the genesis entry.""" key_genesis = self._to_key(0) - value_genesis = self._to_value(BLOCK_GENESIS_ENTRY) + value_genesis = self._to_value(self.get_genesis_block_entry()) self._db.put((self._cf, key_genesis), value_genesis) def _to_key(self, height: int) -> bytes: diff --git a/hathor/p2p/utils.py b/hathor/p2p/utils.py index 33b633d34..6904da0a7 100644 --- a/hathor/p2p/utils.py +++ b/hathor/p2p/utils.py @@ -31,7 +31,7 @@ from hathor.conf.get_settings import get_settings from hathor.indexes.height_index import HeightInfo from hathor.p2p.peer_discovery import DNSPeerDiscovery -from hathor.transaction.genesis import GENESIS_HASH +from hathor.transaction.genesis import get_representation_for_all_genesis def discover_hostname() -> Optional[str]: @@ -75,7 +75,8 @@ def description_to_connection_string(description: str) -> tuple[str, Optional[st def get_genesis_short_hash() -> str: """ Return the first 7 chars of the GENESIS_HASH used for validation that the genesis are the same """ - return GENESIS_HASH.hex()[:7] + settings = get_settings() + return get_representation_for_all_genesis(settings).hex()[:7] def get_settings_hello_dict() -> dict[str, Any]: diff --git a/hathor/simulator/simulator.py b/hathor/simulator/simulator.py index cae937e03..27507baf9 100644 --- a/hathor/simulator/simulator.py +++ b/hathor/simulator/simulator.py @@ -28,7 +28,6 @@ from hathor.simulator.clock import HeapClock, MemoryReactorHeapClock from hathor.simulator.miner.geometric_miner import GeometricMiner from hathor.simulator.tx_generator import RandomTransactionGenerator -from hathor.transaction.genesis import _get_genesis_transactions_unsafe from hathor.util import Random from hathor.wallet import HDWallet @@ -128,7 +127,7 @@ def start(self) -> None: assert not self._started self._started = True self._patches_rc_increment() - first_timestamp = min(tx.timestamp for tx in _get_genesis_transactions_unsafe(None)) + first_timestamp = self.settings.GENESIS_BLOCK_TIMESTAMP dt = self.rng.randint(3600, 120 * 24 * 3600) self._clock.advance(first_timestamp + dt) self.log.debug('randomized step: clock advance start', dt=dt) diff --git a/hathor/transaction/base_transaction.py b/hathor/transaction/base_transaction.py index 0e4b2eee5..ea185893e 100644 --- a/hathor/transaction/base_transaction.py +++ b/hathor/transaction/base_transaction.py @@ -357,7 +357,7 @@ def is_genesis(self) -> bool: if self.hash is None: return False from hathor.transaction.genesis import is_genesis - return is_genesis(self.hash) + return is_genesis(self.hash, settings=self._settings) @abstractmethod def get_funds_fields_from_struct(self, buf: bytes, *, verbose: VerboseCallback = None) -> bytes: diff --git a/hathor/transaction/genesis.py b/hathor/transaction/genesis.py index 408428523..0d567515d 100644 --- a/hathor/transaction/genesis.py +++ b/hathor/transaction/genesis.py @@ -12,71 +12,32 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING -from hathor.conf import HathorSettings -from hathor.transaction import BaseTransaction, Block, Transaction, TxOutput +from hathor.conf.settings import HathorSettings if TYPE_CHECKING: from hathor.transaction.storage import TransactionStorage # noqa: F401 -settings = HathorSettings() -BLOCK_GENESIS = Block( - hash=settings.GENESIS_BLOCK_HASH, - nonce=settings.GENESIS_BLOCK_NONCE, - timestamp=settings.GENESIS_TIMESTAMP, - weight=settings.MIN_BLOCK_WEIGHT, - outputs=[ - TxOutput(settings.GENESIS_TOKENS, settings.GENESIS_OUTPUT_SCRIPT), - ], -) +def get_all_genesis_hashes(settings: HathorSettings) -> list[bytes]: + """Return all genesis hashes.""" + return [ + settings.GENESIS_BLOCK_HASH, + settings.GENESIS_TX1_HASH, + settings.GENESIS_TX2_HASH + ] -TX_GENESIS1 = Transaction( - hash=settings.GENESIS_TX1_HASH, - nonce=settings.GENESIS_TX1_NONCE, - timestamp=settings.GENESIS_TIMESTAMP + 1, - weight=settings.MIN_TX_WEIGHT, -) -TX_GENESIS2 = Transaction( - hash=settings.GENESIS_TX2_HASH, - nonce=settings.GENESIS_TX2_NONCE, - timestamp=settings.GENESIS_TIMESTAMP + 2, - weight=settings.MIN_TX_WEIGHT, -) - -GENESIS = [BLOCK_GENESIS, TX_GENESIS1, TX_GENESIS2] - -GENESIS_HASHES = [settings.GENESIS_BLOCK_HASH, settings.GENESIS_TX1_HASH, settings.GENESIS_TX2_HASH] - - -def _get_genesis_hash() -> bytes: +def get_representation_for_all_genesis(settings: HathorSettings) -> bytes: + """Return a single hash representing all genesis vertices.""" import hashlib h = hashlib.sha256() - for tx in GENESIS: - tx_hash = tx.hash - assert tx_hash is not None + for tx_hash in get_all_genesis_hashes(settings): h.update(tx_hash) return h.digest() -GENESIS_HASH = _get_genesis_hash() - - -def _get_genesis_transactions_unsafe(tx_storage: Optional['TransactionStorage']) -> list[BaseTransaction]: - """You shouldn't get genesis directly. Please, get it from your storage instead.""" - genesis = [] - for tx in GENESIS: - tx2 = tx.clone() - tx2.storage = tx_storage - genesis.append(tx2) - return genesis - - -def is_genesis(hash_bytes: bytes) -> bool: +def is_genesis(hash_bytes: bytes, *, settings: HathorSettings) -> bool: """Check whether hash is from a genesis transaction.""" - for tx in GENESIS: - if hash_bytes == tx.hash: - return True - return False + return hash_bytes in get_all_genesis_hashes(settings) diff --git a/hathor/transaction/storage/transaction_storage.py b/hathor/transaction/storage/transaction_storage.py index 7aa3cffc4..727d4e856 100644 --- a/hathor/transaction/storage/transaction_storage.py +++ b/hathor/transaction/storage/transaction_storage.py @@ -28,7 +28,7 @@ from hathor.indexes.height_index import HeightInfo from hathor.profiler import get_cpu_profiler from hathor.pubsub import PubSubManager -from hathor.transaction.base_transaction import BaseTransaction +from hathor.transaction.base_transaction import BaseTransaction, TxOutput from hathor.transaction.block import Block from hathor.transaction.storage.exceptions import ( TransactionDoesNotExist, @@ -305,7 +305,13 @@ def get_best_block(self) -> Block: def _save_or_verify_genesis(self) -> None: """Save all genesis in the storage.""" self._saving_genesis = True - for tx in self._get_genesis_from_settings(): + genesis_txs = [ + self._construct_genesis_block(), + self._construct_genesis_tx1(), + self._construct_genesis_tx2(), + ] + + for tx in genesis_txs: try: assert tx.hash is not None tx2 = self.get_transaction(tx.hash) @@ -318,11 +324,6 @@ def _save_or_verify_genesis(self) -> None: self._genesis_cache[tx2.hash] = tx2 self._saving_genesis = False - def _get_genesis_from_settings(self) -> list[BaseTransaction]: - """Return all genesis from settings.""" - from hathor.transaction.genesis import _get_genesis_transactions_unsafe - return _get_genesis_transactions_unsafe(self) - def _save_to_weakref(self, tx: BaseTransaction) -> None: """ Save transaction to weakref. """ @@ -1086,6 +1087,48 @@ def compute_transactions_that_became_invalid(self, new_best_height: int) -> list to_remove.append(tx) return to_remove + def _construct_genesis_block(self) -> Block: + """Return the genesis block.""" + block = Block( + storage=self, + nonce=self._settings.GENESIS_BLOCK_NONCE, + timestamp=self._settings.GENESIS_BLOCK_TIMESTAMP, + weight=self._settings.MIN_BLOCK_WEIGHT, + outputs=[ + TxOutput(self._settings.GENESIS_TOKENS, self._settings.GENESIS_OUTPUT_SCRIPT), + ], + ) + block.update_hash() + + assert block.hash == self._settings.GENESIS_BLOCK_HASH + return block + + def _construct_genesis_tx1(self) -> Transaction: + """Return the genesis tx1.""" + tx1 = Transaction( + storage=self, + nonce=self._settings.GENESIS_TX1_NONCE, + timestamp=self._settings.GENESIS_TX1_TIMESTAMP, + weight=self._settings.MIN_TX_WEIGHT, + ) + tx1.update_hash() + + assert tx1.hash == self._settings.GENESIS_TX1_HASH + return tx1 + + def _construct_genesis_tx2(self) -> Transaction: + """Return the genesis tx2.""" + tx2 = Transaction( + storage=self, + nonce=self._settings.GENESIS_TX2_NONCE, + timestamp=self._settings.GENESIS_TX2_TIMESTAMP, + weight=self._settings.MIN_TX_WEIGHT, + ) + tx2.update_hash() + + assert tx2.hash == self._settings.GENESIS_TX2_HASH + return tx2 + class BaseTransactionStorage(TransactionStorage): indexes: Optional[IndexesManager] diff --git a/hathor/transaction/transaction_metadata.py b/hathor/transaction/transaction_metadata.py index fd0039cdf..c7bbbaf72 100644 --- a/hathor/transaction/transaction_metadata.py +++ b/hathor/transaction/transaction_metadata.py @@ -15,6 +15,7 @@ from collections import defaultdict from typing import TYPE_CHECKING, Any, Optional +from hathor.conf.get_settings import get_settings from hathor.feature_activation.feature import Feature from hathor.feature_activation.model.feature_state import FeatureState from hathor.transaction.validation_state import ValidationState @@ -127,8 +128,10 @@ def __init__( self.feature_activation_bit_counts = feature_activation_bit_counts + settings = get_settings() + # Genesis specific: - if hash is not None and is_genesis(hash): + if hash is not None and is_genesis(hash, settings=settings): self.validation = ValidationState.FULL def get_tx(self) -> 'BaseTransaction': @@ -248,10 +251,8 @@ def to_json_extended(self, tx_storage: 'TransactionStorage') -> dict[str, Any]: @classmethod def create_from_json(cls, data: dict[str, Any]) -> 'TransactionMetadata': - from hathor.transaction.genesis import is_genesis - - meta = cls() - meta.hash = bytes.fromhex(data['hash']) if data['hash'] else None + hash_ = bytes.fromhex(data['hash']) if data['hash'] else None + meta = cls(hash=hash_) for idx, hashes in data['spent_outputs']: for h_hex in hashes: meta.spent_outputs[idx].append(bytes.fromhex(h_hex)) @@ -293,9 +294,6 @@ def create_from_json(cls, data: dict[str, Any]) -> 'TransactionMetadata': _val_name = data.get('validation', None) meta.validation = ValidationState.from_name(_val_name) if _val_name is not None else ValidationState.INITIAL - if meta.hash is not None and is_genesis(meta.hash): - meta.validation = ValidationState.FULL - return meta def clone(self) -> 'TransactionMetadata': diff --git a/tests/others/fixtures/invalid_byte_hathor_settings_fixture.yml b/tests/others/fixtures/invalid_byte_hathor_settings_fixture.yml index a425f1cdd..b05b8f246 100644 --- a/tests/others/fixtures/invalid_byte_hathor_settings_fixture.yml +++ b/tests/others/fixtures/invalid_byte_hathor_settings_fixture.yml @@ -7,7 +7,7 @@ ENABLE_PEER_WHITELIST: true WHITELIST_URL: https://hathor-public-files.s3.amazonaws.com/whitelist_peer_ids GENESIS_OUTPUT_SCRIPT: 76a9147fd4ae0e4fb2d2854e76d359029d8078bb99649e88ac -GENESIS_TIMESTAMP: 1578075305 +GENESIS_BLOCK_TIMESTAMP: 1578075305 GENESIS_BLOCK_NONCE: 2591358 GENESIS_BLOCK_HASH: 000006cb93385b8b87a545a1cbb6197e6caff600c12cc12fc54250d39c8088fc GENESIS_TX1_NONCE: 7715 diff --git a/tests/others/fixtures/invalid_features_hathor_settings_fixture.yml b/tests/others/fixtures/invalid_features_hathor_settings_fixture.yml index e993f0cee..c2103afef 100644 --- a/tests/others/fixtures/invalid_features_hathor_settings_fixture.yml +++ b/tests/others/fixtures/invalid_features_hathor_settings_fixture.yml @@ -7,7 +7,7 @@ ENABLE_PEER_WHITELIST: true WHITELIST_URL: https://hathor-public-files.s3.amazonaws.com/whitelist_peer_ids GENESIS_OUTPUT_SCRIPT: 76a9147fd4ae0e4fb2d2854e76d359029d8078bb99649e88ac -GENESIS_TIMESTAMP: 1578075305 +GENESIS_BLOCK_TIMESTAMP: 1578075305 GENESIS_BLOCK_NONCE: 2591358 GENESIS_BLOCK_HASH: 000006cb93385b8b87a545a1cbb6197e6caff600c12cc12fc54250d39c8088fc GENESIS_TX1_NONCE: 7715 diff --git a/tests/others/fixtures/missing_hathor_settings_fixture.yml b/tests/others/fixtures/missing_hathor_settings_fixture.yml index f03053bc9..81719c264 100644 --- a/tests/others/fixtures/missing_hathor_settings_fixture.yml +++ b/tests/others/fixtures/missing_hathor_settings_fixture.yml @@ -6,7 +6,7 @@ ENABLE_PEER_WHITELIST: true WHITELIST_URL: https://hathor-public-files.s3.amazonaws.com/whitelist_peer_ids GENESIS_OUTPUT_SCRIPT: 76a9147fd4ae0e4fb2d2854e76d359029d8078bb99649e88ac -GENESIS_TIMESTAMP: 1578075305 +GENESIS_BLOCK_TIMESTAMP: 1578075305 GENESIS_BLOCK_NONCE: 2591358 GENESIS_BLOCK_HASH: 000006cb93385b8b87a545a1cbb6197e6caff600c12cc12fc54250d39c8088fc GENESIS_TX1_NONCE: 7715 diff --git a/tests/others/fixtures/valid_hathor_settings_fixture.yml b/tests/others/fixtures/valid_hathor_settings_fixture.yml index a1c8a847a..b0198476f 100644 --- a/tests/others/fixtures/valid_hathor_settings_fixture.yml +++ b/tests/others/fixtures/valid_hathor_settings_fixture.yml @@ -7,7 +7,7 @@ ENABLE_PEER_WHITELIST: true WHITELIST_URL: https://hathor-public-files.s3.amazonaws.com/whitelist_peer_ids GENESIS_OUTPUT_SCRIPT: 76a9147fd4ae0e4fb2d2854e76d359029d8078bb99649e88ac -GENESIS_TIMESTAMP: 1578075305 +GENESIS_BLOCK_TIMESTAMP: 1578075305 GENESIS_BLOCK_NONCE: 2591358 GENESIS_BLOCK_HASH: 000006cb93385b8b87a545a1cbb6197e6caff600c12cc12fc54250d39c8088fc GENESIS_TX1_NONCE: 7715 diff --git a/tests/others/test_hathor_settings.py b/tests/others/test_hathor_settings.py index e0bcf82e9..12040a0ca 100644 --- a/tests/others/test_hathor_settings.py +++ b/tests/others/test_hathor_settings.py @@ -41,7 +41,7 @@ def test_valid_hathor_settings_from_yaml(filepath): MIN_TX_WEIGHT_COEFFICIENT=0, MIN_TX_WEIGHT=8, GENESIS_OUTPUT_SCRIPT=bytes.fromhex('76a9147fd4ae0e4fb2d2854e76d359029d8078bb99649e88ac'), - GENESIS_TIMESTAMP=1578075305, + GENESIS_BLOCK_TIMESTAMP=1578075305, GENESIS_BLOCK_NONCE=2591358, GENESIS_BLOCK_HASH=bytes.fromhex('000006cb93385b8b87a545a1cbb6197e6caff600c12cc12fc54250d39c8088fc'), GENESIS_TX1_NONCE=7715, diff --git a/tests/p2p/test_split_brain.py b/tests/p2p/test_split_brain.py index 7bc2f44c6..804377f99 100644 --- a/tests/p2p/test_split_brain.py +++ b/tests/p2p/test_split_brain.py @@ -14,9 +14,8 @@ class BaseHathorSyncMethodsTestCase(unittest.TestCase): def setUp(self): super().setUp() - from hathor.transaction.genesis import _get_genesis_transactions_unsafe - first_timestamp = min(tx.timestamp for tx in _get_genesis_transactions_unsafe(None)) + first_timestamp = self._settings.GENESIS_BLOCK_TIMESTAMP self.clock.advance(first_timestamp + self.rng.randint(3600, 120*24*3600)) self.network = 'testnet' diff --git a/tests/resources/wallet/test_thin_wallet.py b/tests/resources/wallet/test_thin_wallet.py index 033a2050f..e9d0d4b31 100644 --- a/tests/resources/wallet/test_thin_wallet.py +++ b/tests/resources/wallet/test_thin_wallet.py @@ -5,7 +5,7 @@ from hathor.conf import HathorSettings from hathor.crypto.util import decode_address from hathor.daa import minimum_tx_weight -from hathor.transaction import Transaction, TxInput, TxOutput, genesis +from hathor.transaction import Transaction, TxInput, TxOutput from hathor.transaction.scripts import P2PKH, create_output_script, parse_address_script from hathor.wallet.resources.thin_wallet import ( AddressHistoryResource, @@ -275,7 +275,7 @@ def test_error_request(self): resource = SendTokensResource(self.manager) request = TestDummyRequest('POST', 'thin_wallet/send_tokens', {}) - dummy_tx = genesis.BLOCK_GENESIS + dummy_tx = Transaction() self.assertIsNotNone(request._finishedDeferreds) resource._err_tx_resolve('Error', _Context(tx=dummy_tx, request=request), 'error') diff --git a/tests/tx/test_block.py b/tests/tx/test_block.py index 0b925a236..a7b362dfe 100644 --- a/tests/tx/test_block.py +++ b/tests/tx/test_block.py @@ -17,13 +17,17 @@ import pytest from hathor.conf import HathorSettings +from hathor.conf.get_settings import get_settings from hathor.transaction import Block, TransactionMetadata -from hathor.transaction.genesis import BLOCK_GENESIS -from hathor.transaction.storage import TransactionStorage +from hathor.transaction.storage import TransactionMemoryStorage, TransactionStorage def test_calculate_feature_activation_bit_counts_genesis(): - result = BLOCK_GENESIS.calculate_feature_activation_bit_counts() + settings = get_settings() + storage = TransactionMemoryStorage() + genesis_block = storage.get_transaction(settings.GENESIS_BLOCK_HASH) + assert isinstance(genesis_block, Block) + result = genesis_block.calculate_feature_activation_bit_counts() assert result == [0, 0, 0, 0] diff --git a/tests/tx/test_indexes2.py b/tests/tx/test_indexes2.py index ea8aea4ea..edca6c0c7 100644 --- a/tests/tx/test_indexes2.py +++ b/tests/tx/test_indexes2.py @@ -25,7 +25,7 @@ def setUp(self): # how many transactions will be generated on the same timestamp before increasing it by 1 self.transactions = [] repetitions = [1, 1, 10, 10, 10, 2, 1, 0, 0, 5, 5, 5, 0, 1, 1, 10, 10, 10, 1, 2, 3, 1, 100, 100, 1, 100, 0, 1] - ts = settings.GENESIS_TIMESTAMP + ts = settings.GENESIS_BLOCK_TIMESTAMP for rep in repetitions: for _ in range(rep): tx = FakeTransaction(self.rng.randbytes(32), ts) diff --git a/tests/tx/test_mining.py b/tests/tx/test_mining.py index 8524966dd..822231907 100644 --- a/tests/tx/test_mining.py +++ b/tests/tx/test_mining.py @@ -42,7 +42,7 @@ def test_block_template_after_genesis(self) -> None: reward=settings.INITIAL_TOKEN_UNITS_PER_BLOCK * 100, weight=1.0, timestamp_now=int(manager.reactor.seconds()), - timestamp_min=settings.GENESIS_TIMESTAMP + 3, + timestamp_min=settings.GENESIS_BLOCK_TIMESTAMP + 3, timestamp_max=0xffffffff, # no limit for next block after genesis # parents=[tx.hash for tx in self.genesis_blocks + self.genesis_txs], parents=block_templates[0].parents, diff --git a/tests/tx/test_stratum.py b/tests/tx/test_stratum.py index 42d5082df..f059aacb8 100644 --- a/tests/tx/test_stratum.py +++ b/tests/tx/test_stratum.py @@ -21,6 +21,7 @@ StratumFactory, ) from hathor.transaction.block import Block +from hathor.transaction.storage import TransactionMemoryStorage from tests import unittest @@ -252,8 +253,8 @@ class BaseStratumClientTest(unittest.TestCase): def setUp(self): super().setUp() - from hathor.transaction.genesis import _get_genesis_transactions_unsafe - self.block = next(x for x in _get_genesis_transactions_unsafe(None) if x.is_block) + storage = TransactionMemoryStorage() + self.block = storage.get_transaction(self._settings.GENESIS_BLOCK_HASH) self.transport = StringTransportWithDisconnection() self.protocol = StratumClient() self.protocol.makeConnection(self.transport) diff --git a/tests/tx/test_tx_storage.py b/tests/tx/test_tx_storage.py index b2f83a0a2..909164169 100644 --- a/tests/tx/test_tx_storage.py +++ b/tests/tx/test_tx_storage.py @@ -18,7 +18,6 @@ from tests.utils import ( BURN_ADDRESS, HAS_ROCKSDB, - MIN_TIMESTAMP, add_blocks_unlock_reward, add_new_blocks, add_new_transactions, @@ -61,7 +60,8 @@ def setUp(self): block_parents = [tx.hash for tx in chain(self.genesis_blocks, self.genesis_txs)] output = TxOutput(200, P2PKH.create_output_script(BURN_ADDRESS)) - self.block = Block(timestamp=MIN_TIMESTAMP, weight=12, outputs=[output], parents=block_parents, + previous_timestamp = artifacts.settings.GENESIS_TX2_TIMESTAMP + self.block = Block(timestamp=previous_timestamp + 1, weight=12, outputs=[output], parents=block_parents, nonce=100781, storage=self.tx_storage) self.block.resolve() self.manager.verification_service.verify(self.block) @@ -77,7 +77,7 @@ def setUp(self): '620e78362cf2d908e9057ac235a63')) self.tx = Transaction( - timestamp=MIN_TIMESTAMP + 2, weight=10, nonce=932049, inputs=[tx_input], outputs=[output], + timestamp=previous_timestamp + 2, weight=10, nonce=932049, inputs=[tx_input], outputs=[output], tokens=[bytes.fromhex('0023be91834c973d6a6ddd1a0ae411807b7c8ef2a015afb5177ee64b666ce602')], parents=tx_parents, storage=self.tx_storage) self.tx.resolve() @@ -100,16 +100,6 @@ def test_genesis_ref(self): tx2 = self.tx_storage.get_transaction(tx.hash) self.assertTrue(tx is tx2) - from hathor.transaction.genesis import _get_genesis_transactions_unsafe - genesis_from_settings = _get_genesis_transactions_unsafe(None) - for tx in genesis_from_settings: - tx2 = self.tx_storage.get_transaction(tx.hash) - self.assertTrue(tx is not tx2) - for tx3 in genesis_set: - self.assertTrue(tx is not tx3) - if tx2 == tx3: - self.assertTrue(tx2 is tx3) - def test_genesis(self): self.assertEqual(1, len(self.genesis_blocks)) self.assertEqual(2, len(self.genesis_txs)) diff --git a/tests/unittest.py b/tests/unittest.py index e9ccfdbb3..837bec2e5 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -275,9 +275,9 @@ def assertIsTopological(self, tx_sequence: Iterator[BaseTransaction], message: O An initial set can be optionally provided. """ - from hathor.transaction.genesis import GENESIS_HASHES + from hathor.transaction.genesis import get_all_genesis_hashes - valid_deps = set(GENESIS_HASHES if initial is None else initial) + valid_deps = set(get_all_genesis_hashes(self._settings) if initial is None else initial) for tx in tx_sequence: assert tx.hash is not None diff --git a/tests/utils.py b/tests/utils.py index 2878e60a2..6a9403666 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -18,7 +18,7 @@ from hathor.event.model.event_data import TxData, TxMetadata from hathor.event.model.event_type import EventType from hathor.manager import HathorManager -from hathor.transaction import BaseTransaction, Transaction, TxInput, TxOutput, genesis +from hathor.transaction import BaseTransaction, Transaction, TxInput, TxOutput from hathor.transaction.scripts import P2PKH, HathorScript, Opcode, parse_address_script from hathor.transaction.token_creation_tx import TokenCreationTransaction from hathor.transaction.util import get_deposit_amount @@ -33,8 +33,6 @@ settings = HathorSettings() -MIN_TIMESTAMP = genesis.GENESIS[-1].timestamp + 1 - # useful for adding blocks to a different wallet BURN_ADDRESS = bytes.fromhex('28acbfb94571417423c1ed66f706730c4aea516ac5762cccb8') From 1cb8d7860e3b33eda88e32afdafdc06ace31c927 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Tue, 10 Oct 2023 15:56:49 -0300 Subject: [PATCH 22/26] refactor(verification): create vertex verifiers --- hathor/builder/builder.py | 18 ++++- hathor/builder/cli_builder.py | 5 +- hathor/verification/block_verification.py | 47 ------------- hathor/verification/block_verifier.py | 50 ++++++++++++++ .../merge_mined_block_verifier.py | 19 ++++++ ...=> token_creation_transaction_verifier.py} | 17 +++-- .../verification/transaction_verification.py | 53 --------------- hathor/verification/transaction_verifier.py | 56 ++++++++++++++++ hathor/verification/verification_service.py | 67 ++++++++++++++++--- hathor/verification/vertex_verifier.py | 22 ++++++ 10 files changed, 232 insertions(+), 122 deletions(-) delete mode 100644 hathor/verification/block_verification.py create mode 100644 hathor/verification/block_verifier.py create mode 100644 hathor/verification/merge_mined_block_verifier.py rename hathor/verification/{token_creation_transaction_verification.py => token_creation_transaction_verifier.py} (55%) delete mode 100644 hathor/verification/transaction_verification.py create mode 100644 hathor/verification/transaction_verifier.py create mode 100644 hathor/verification/vertex_verifier.py diff --git a/hathor/builder/builder.py b/hathor/builder/builder.py index ecb2bd02c..37bfcb8fe 100644 --- a/hathor/builder/builder.py +++ b/hathor/builder/builder.py @@ -41,7 +41,7 @@ TransactionStorage, ) from hathor.util import Random, Reactor, get_environment_info -from hathor.verification.verification_service import VerificationService +from hathor.verification.verification_service import VerificationService, VertexVerifiers from hathor.wallet import BaseWallet, Wallet logger = get_logger() @@ -102,6 +102,7 @@ def __init__(self) -> None: self._feature_service: Optional[FeatureService] = None self._bit_signaling_service: Optional[BitSignalingService] = None + self._vertex_verifiers: Optional[VertexVerifiers] = None self._verification_service: Optional[VerificationService] = None self._rocksdb_path: Optional[str] = None @@ -432,10 +433,18 @@ def _get_or_create_bit_signaling_service(self, tx_storage: TransactionStorage) - def _get_or_create_verification_service(self) -> VerificationService: if self._verification_service is None: - self._verification_service = VerificationService() + verifiers = self._get_or_create_vertex_verifiers() + self._verification_service = VerificationService(verifiers=verifiers) return self._verification_service + def _get_or_create_vertex_verifiers(self) -> VertexVerifiers: + if self._vertex_verifiers is None: + settings = self._get_or_create_settings() + self._vertex_verifiers = VertexVerifiers.create_defaults(settings=settings) + + return self._vertex_verifiers + def use_memory(self) -> 'Builder': self.check_if_can_modify() self._storage_type = StorageType.MEMORY @@ -533,6 +542,11 @@ def set_verification_service(self, verification_service: VerificationService) -> self._verification_service = verification_service return self + def set_vertex_verifiers(self, vertex_verifiers: VertexVerifiers) -> 'Builder': + self.check_if_can_modify() + self._vertex_verifiers = vertex_verifiers + return self + def set_reactor(self, reactor: Reactor) -> 'Builder': self.check_if_can_modify() self._reactor = reactor diff --git a/hathor/builder/cli_builder.py b/hathor/builder/cli_builder.py index 7dab5bdf5..58e8d83b4 100644 --- a/hathor/builder/cli_builder.py +++ b/hathor/builder/cli_builder.py @@ -35,7 +35,7 @@ from hathor.pubsub import PubSubManager from hathor.stratum import StratumFactory from hathor.util import Random, Reactor -from hathor.verification.verification_service import VerificationService +from hathor.verification.verification_service import VerificationService, VertexVerifiers from hathor.wallet import BaseWallet, HDWallet, Wallet logger = get_logger() @@ -202,7 +202,8 @@ def create_manager(self, reactor: Reactor) -> HathorManager: not_support_features=self._args.signal_not_support ) - verification_service = VerificationService() + vertex_verifiers = VertexVerifiers.create_defaults(settings=settings) + verification_service = VerificationService(verifiers=vertex_verifiers) p2p_manager = ConnectionsManager( reactor, diff --git a/hathor/verification/block_verification.py b/hathor/verification/block_verification.py deleted file mode 100644 index 3e47aa254..000000000 --- a/hathor/verification/block_verification.py +++ /dev/null @@ -1,47 +0,0 @@ -# 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 hathor.profiler import get_cpu_profiler -from hathor.transaction import Block - -cpu = get_cpu_profiler() - - -def verify_basic(block: Block, *, skip_block_weight_verification: bool = False) -> None: - """Partially run validations, the ones that need parents/inputs are skipped.""" - if not skip_block_weight_verification: - block.verify_weight() - block.verify_reward() - - -@cpu.profiler(key=lambda block: 'block-verify!{}'.format(block.hash.hex())) -def verify(block: Block) -> None: - """ - (1) confirms at least two pending transactions and references last block - (2) solves the pow with the correct weight (done in HathorManager) - (3) creates the correct amount of tokens in the output (done in HathorManager) - (4) all parents must exist and have timestamp smaller than ours - (5) data field must contain at most BLOCK_DATA_MAX_SIZE bytes - """ - # TODO Should we validate a limit of outputs? - if block.is_genesis: - # TODO do genesis validation - return - - block.verify_without_storage() - - # (1) and (4) - block.verify_parents() - - block.verify_height() diff --git a/hathor/verification/block_verifier.py b/hathor/verification/block_verifier.py new file mode 100644 index 000000000..dd8903f72 --- /dev/null +++ b/hathor/verification/block_verifier.py @@ -0,0 +1,50 @@ +# 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 hathor.profiler import get_cpu_profiler +from hathor.transaction import Block +from hathor.verification.vertex_verifier import VertexVerifier + +cpu = get_cpu_profiler() + + +class BlockVerifier(VertexVerifier): + __slots__ = () + + def verify_basic(self, block: Block, *, skip_block_weight_verification: bool = False) -> None: + """Partially run validations, the ones that need parents/inputs are skipped.""" + if not skip_block_weight_verification: + block.verify_weight() + block.verify_reward() + + @cpu.profiler(key=lambda _, block: 'block-verify!{}'.format(block.hash.hex())) + def verify(self, block: Block) -> None: + """ + (1) confirms at least two pending transactions and references last block + (2) solves the pow with the correct weight (done in HathorManager) + (3) creates the correct amount of tokens in the output (done in HathorManager) + (4) all parents must exist and have timestamp smaller than ours + (5) data field must contain at most BLOCK_DATA_MAX_SIZE bytes + """ + # TODO Should we validate a limit of outputs? + if block.is_genesis: + # TODO do genesis validation + return + + block.verify_without_storage() + + # (1) and (4) + block.verify_parents() + + block.verify_height() diff --git a/hathor/verification/merge_mined_block_verifier.py b/hathor/verification/merge_mined_block_verifier.py new file mode 100644 index 000000000..efbfc4c07 --- /dev/null +++ b/hathor/verification/merge_mined_block_verifier.py @@ -0,0 +1,19 @@ +# 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 hathor.verification.block_verifier import BlockVerifier + + +class MergeMinedBlockVerifier(BlockVerifier): + __slots__ = () diff --git a/hathor/verification/token_creation_transaction_verification.py b/hathor/verification/token_creation_transaction_verifier.py similarity index 55% rename from hathor/verification/token_creation_transaction_verification.py rename to hathor/verification/token_creation_transaction_verifier.py index b1d9622b2..fee1bec0e 100644 --- a/hathor/verification/token_creation_transaction_verification.py +++ b/hathor/verification/token_creation_transaction_verifier.py @@ -13,13 +13,16 @@ # limitations under the License. from hathor.transaction.token_creation_tx import TokenCreationTransaction -from hathor.verification import transaction_verification +from hathor.verification.transaction_verifier import TransactionVerifier -def verify(tx: TokenCreationTransaction, *, reject_locked_reward: bool = True) -> None: - """ Run all validations as regular transactions plus validation on token info. +class TokenCreationTransactionVerifier(TransactionVerifier): + __slots__ = () - We also overload verify_sum to make some different checks - """ - transaction_verification.verify(tx, reject_locked_reward=reject_locked_reward) - tx.verify_token_info() + def verify(self, tx: TokenCreationTransaction, *, reject_locked_reward: bool = True) -> None: + """ Run all validations as regular transactions plus validation on token info. + + We also overload verify_sum to make some different checks + """ + super().verify(tx, reject_locked_reward=reject_locked_reward) + tx.verify_token_info() diff --git a/hathor/verification/transaction_verification.py b/hathor/verification/transaction_verification.py deleted file mode 100644 index 02d887a10..000000000 --- a/hathor/verification/transaction_verification.py +++ /dev/null @@ -1,53 +0,0 @@ -# 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 hathor.profiler import get_cpu_profiler -from hathor.transaction import Transaction - -cpu = get_cpu_profiler() - - -def verify_basic(transaction: Transaction) -> None: - """Partially run validations, the ones that need parents/inputs are skipped.""" - if transaction.is_genesis: - # TODO do genesis validation? - return - transaction.verify_parents_basic() - transaction.verify_weight() - transaction.verify_without_storage() - - -@cpu.profiler(key=lambda tx: 'tx-verify!{}'.format(tx.hash.hex())) -def verify(tx: Transaction, *, reject_locked_reward: bool = True) -> None: - """ Common verification for all transactions: - (i) number of inputs is at most 256 - (ii) number of outputs is at most 256 - (iii) confirms at least two pending transactions - (iv) solves the pow (we verify weight is correct in HathorManager) - (v) validates signature of inputs - (vi) validates public key and output (of the inputs) addresses - (vii) validate that both parents are valid - (viii) validate input's timestamps - (ix) validate inputs and outputs sum - """ - if tx.is_genesis: - # TODO do genesis validation - return - tx.verify_without_storage() - tx.verify_sigops_input() - tx.verify_inputs() # need to run verify_inputs first to check if all inputs exist - tx.verify_parents() - tx.verify_sum() - if reject_locked_reward: - tx.verify_reward_locked() diff --git a/hathor/verification/transaction_verifier.py b/hathor/verification/transaction_verifier.py new file mode 100644 index 000000000..8c3711524 --- /dev/null +++ b/hathor/verification/transaction_verifier.py @@ -0,0 +1,56 @@ +# 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 hathor.profiler import get_cpu_profiler +from hathor.transaction import Transaction +from hathor.verification.vertex_verifier import VertexVerifier + +cpu = get_cpu_profiler() + + +class TransactionVerifier(VertexVerifier): + __slots__ = () + + def verify_basic(self, tx: Transaction) -> None: + """Partially run validations, the ones that need parents/inputs are skipped.""" + if tx.is_genesis: + # TODO do genesis validation? + return + tx.verify_parents_basic() + tx.verify_weight() + tx.verify_without_storage() + + @cpu.profiler(key=lambda _, tx: 'tx-verify!{}'.format(tx.hash.hex())) + def verify(self, tx: Transaction, *, reject_locked_reward: bool = True) -> None: + """ Common verification for all transactions: + (i) number of inputs is at most 256 + (ii) number of outputs is at most 256 + (iii) confirms at least two pending transactions + (iv) solves the pow (we verify weight is correct in HathorManager) + (v) validates signature of inputs + (vi) validates public key and output (of the inputs) addresses + (vii) validate that both parents are valid + (viii) validate input's timestamps + (ix) validate inputs and outputs sum + """ + if tx.is_genesis: + # TODO do genesis validation + return + tx.verify_without_storage() + tx.verify_sigops_input() + tx.verify_inputs() # need to run verify_inputs first to check if all inputs exist + tx.verify_parents() + tx.verify_sum() + if reject_locked_reward: + tx.verify_reward_locked() diff --git a/hathor/verification/verification_service.py b/hathor/verification/verification_service.py index 2a98cb662..450de491e 100644 --- a/hathor/verification/verification_service.py +++ b/hathor/verification/verification_service.py @@ -12,15 +12,45 @@ # See the License for the specific language governing permissions and # limitations under the License. -from hathor.transaction import BaseTransaction, Block, Transaction, TxVersion +from typing import NamedTuple + +from hathor.conf.settings import HathorSettings +from hathor.transaction import BaseTransaction, Block, MergeMinedBlock, Transaction, TxVersion from hathor.transaction.exceptions import TxValidationError from hathor.transaction.token_creation_tx import TokenCreationTransaction from hathor.transaction.validation_state import ValidationState -from hathor.verification import block_verification, token_creation_transaction_verification, transaction_verification +from hathor.verification.block_verifier import BlockVerifier +from hathor.verification.merge_mined_block_verifier import MergeMinedBlockVerifier +from hathor.verification.token_creation_transaction_verifier import TokenCreationTransactionVerifier +from hathor.verification.transaction_verifier import TransactionVerifier + + +class VertexVerifiers(NamedTuple): + """A group of verifier instances, one for each vertex type.""" + block: BlockVerifier + merge_mined_block: MergeMinedBlockVerifier + tx: TransactionVerifier + token_creation_tx: TokenCreationTransactionVerifier + + @classmethod + def create_defaults(cls, *, settings: HathorSettings) -> 'VertexVerifiers': + """ + Create a VertexVerifiers instance using the default verifier for each vertex type, + from all required dependencies. + """ + return VertexVerifiers( + block=BlockVerifier(settings=settings), + merge_mined_block=MergeMinedBlockVerifier(settings=settings), + tx=TransactionVerifier(settings=settings), + token_creation_tx=TokenCreationTransactionVerifier(settings=settings), + ) class VerificationService: - __slots__ = () + __slots__ = ('verifiers', ) + + def __init__(self, *, verifiers: VertexVerifiers) -> None: + self.verifiers = verifiers def validate_basic(self, vertex: BaseTransaction, *, skip_block_weight_verification: bool = False) -> bool: """ Run basic validations (all that are possible without dependencies) and update the validation state. @@ -70,12 +100,24 @@ def verify_basic(self, vertex: BaseTransaction, *, skip_block_weight_verificatio Used by `self.validate_basic`. Should not modify the validation state.""" match vertex.version: - case TxVersion.REGULAR_BLOCK | TxVersion.MERGE_MINED_BLOCK: + case TxVersion.REGULAR_BLOCK: assert isinstance(vertex, Block) - block_verification.verify_basic(vertex, skip_block_weight_verification=skip_block_weight_verification) - case TxVersion.REGULAR_TRANSACTION | TxVersion.TOKEN_CREATION_TRANSACTION: + self.verifiers.block.verify_basic( + vertex, + skip_block_weight_verification=skip_block_weight_verification + ) + case TxVersion.MERGE_MINED_BLOCK: + assert isinstance(vertex, MergeMinedBlock) + self.verifiers.merge_mined_block.verify_basic( + vertex, + skip_block_weight_verification=skip_block_weight_verification + ) + case TxVersion.REGULAR_TRANSACTION: assert isinstance(vertex, Transaction) - transaction_verification.verify_basic(vertex) + self.verifiers.tx.verify_basic(vertex) + case TxVersion.TOKEN_CREATION_TRANSACTION: + assert isinstance(vertex, TokenCreationTransaction) + self.verifiers.token_creation_tx.verify_basic(vertex) case _: raise NotImplementedError @@ -84,15 +126,18 @@ def verify(self, vertex: BaseTransaction, *, reject_locked_reward: bool = True) Used by `self.validate_full`. Should not modify the validation state.""" match vertex.version: - case TxVersion.REGULAR_BLOCK | TxVersion.MERGE_MINED_BLOCK: + case TxVersion.REGULAR_BLOCK: assert isinstance(vertex, Block) - block_verification.verify(vertex) + self.verifiers.block.verify(vertex) + case TxVersion.MERGE_MINED_BLOCK: + assert isinstance(vertex, MergeMinedBlock) + self.verifiers.merge_mined_block.verify(vertex) case TxVersion.REGULAR_TRANSACTION: assert isinstance(vertex, Transaction) - transaction_verification.verify(vertex, reject_locked_reward=reject_locked_reward) + self.verifiers.tx.verify(vertex, reject_locked_reward=reject_locked_reward) case TxVersion.TOKEN_CREATION_TRANSACTION: assert isinstance(vertex, TokenCreationTransaction) - token_creation_transaction_verification.verify(vertex, reject_locked_reward=reject_locked_reward) + self.verifiers.token_creation_tx.verify(vertex, reject_locked_reward=reject_locked_reward) case _: raise NotImplementedError diff --git a/hathor/verification/vertex_verifier.py b/hathor/verification/vertex_verifier.py new file mode 100644 index 000000000..360450116 --- /dev/null +++ b/hathor/verification/vertex_verifier.py @@ -0,0 +1,22 @@ +# 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 hathor.conf.settings import HathorSettings + + +class VertexVerifier: + __slots__ = ('_settings', ) + + def __init__(self, *, settings: HathorSettings): + self._settings = settings From 67085e3ee40a512bc2df18537ea732349c8bef18 Mon Sep 17 00:00:00 2001 From: Gabriel Levcovitz Date: Fri, 6 Oct 2023 16:44:22 -0300 Subject: [PATCH 23/26] chore: improve push_tx log --- hathor/transaction/resources/push_tx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hathor/transaction/resources/push_tx.py b/hathor/transaction/resources/push_tx.py index 0b668274d..8db827edf 100644 --- a/hathor/transaction/resources/push_tx.py +++ b/hathor/transaction/resources/push_tx.py @@ -101,9 +101,9 @@ def handle_push_tx(self, params: dict[str, Any], client_addr: str) -> dict[str, self.manager.push_tx(tx, allow_non_standard_script=self.allow_non_standard_script, max_output_script_size=self.max_output_script_size) except (InvalidNewTransaction, TxValidationError) as e: - self.log.warn('push tx rejected', exc_info=True) success = False message = str(e) + self.log.warn('push tx rejected', reason=repr(e)) data = {'success': success, 'message': message} if success: data['tx'] = tx.to_json() From 45c7ba55b2665972642dd19107482d58a3ce05d2 Mon Sep 17 00:00:00 2001 From: Marcelo Salhab Brogliato Date: Fri, 13 Oct 2023 00:29:54 -0500 Subject: [PATCH 24/26] fix(sync-v2): Stop streaming if current block becomes voided --- hathor/p2p/sync_v2/streamers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hathor/p2p/sync_v2/streamers.py b/hathor/p2p/sync_v2/streamers.py index 191cb9372..1c8fac80e 100644 --- a/hathor/p2p/sync_v2/streamers.py +++ b/hathor/p2p/sync_v2/streamers.py @@ -143,6 +143,12 @@ def send_next(self) -> None: assert cur is not None assert cur.hash is not None + meta = cur.get_metadata() + if meta.voided_by: + self.stop() + self.node_sync.send_blocks_end(StreamEnd.STREAM_BECAME_VOIDED) + return + if cur.hash == self.end_hash: # only send the last when not reverse if not self.reverse: From 889bf5d25f5cb1c84c484e65097bf3242551ad1d Mon Sep 17 00:00:00 2001 From: Marcelo Salhab Brogliato Date: Tue, 17 Oct 2023 13:25:33 -0500 Subject: [PATCH 25/26] test(sync-v1): Reset rate limit hit counter after simulation --- hathor/p2p/manager.py | 1 + tests/p2p/test_sync_rate_limiter.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/hathor/p2p/manager.py b/hathor/p2p/manager.py index 4e6639185..94bd07ff2 100644 --- a/hathor/p2p/manager.py +++ b/hathor/p2p/manager.py @@ -227,6 +227,7 @@ def do_discovery(self) -> None: def disable_rate_limiter(self) -> None: """Disable global rate limiter.""" self.rate_limiter.unset_limit(self.GlobalRateLimiter.SEND_TIPS) + self.rate_limiter.reset(self.GlobalRateLimiter.SEND_TIPS) def enable_rate_limiter(self, max_hits: int = 16, window_seconds: float = 1) -> None: """Enable global rate limiter. This method can be called to change the current rate limit.""" diff --git a/tests/p2p/test_sync_rate_limiter.py b/tests/p2p/test_sync_rate_limiter.py index 054543f78..f9d21114a 100644 --- a/tests/p2p/test_sync_rate_limiter.py +++ b/tests/p2p/test_sync_rate_limiter.py @@ -25,6 +25,8 @@ def test_sync_rate_limiter(self): self.simulator.add_connection(conn12) self.simulator.run(3600) + # Disable to reset all previous hits to the rate limiter. + manager2.connections.disable_rate_limiter() manager2.connections.enable_rate_limiter(8, 2) connected_peers2 = list(manager2.connections.connected_peers.values()) From e3056451439465ca33e5e679ba23884debacf115 Mon Sep 17 00:00:00 2001 From: Marcelo Salhab Brogliato Date: Fri, 22 Sep 2023 02:08:00 -0500 Subject: [PATCH 26/26] feat(p2p): relay all recently-seen peers for neighbors. --- hathor/p2p/manager.py | 31 ++++++++++++++++++++++++---- hathor/p2p/peer_id.py | 3 +++ hathor/p2p/protocol.py | 5 ++++- hathor/p2p/resources/status.py | 15 ++++++++------ hathor/p2p/states/ready.py | 37 +++++++++++++++++++++------------- hathor/p2p/sync_v1/agent.py | 16 ++++++++------- tests/p2p/test_protocol.py | 18 +++++++++-------- 7 files changed, 85 insertions(+), 40 deletions(-) diff --git a/hathor/p2p/manager.py b/hathor/p2p/manager.py index 94bd07ff2..7aefaee3f 100644 --- a/hathor/p2p/manager.py +++ b/hathor/p2p/manager.py @@ -157,6 +157,9 @@ def __init__(self, # List of known peers. self.peer_storage = PeerStorage() # dict[string (peer.id), PeerId] + # Maximum unseen time before removing a peer (seconds). + self.max_peer_unseen_dt: float = 30 * 60 # 30-minutes + # A timer to try to reconnect to the disconnect known peers. self.lc_reconnect = LoopingCall(self.reconnect_to_all) self.lc_reconnect.clock = self.reactor @@ -394,11 +397,15 @@ def on_peer_ready(self, protocol: HathorProtocol) -> None: protocol.enable_sync() # Notify other peers about this new peer connection. + self.relay_peer_to_ready_connections(protocol.peer) + + def relay_peer_to_ready_connections(self, peer: PeerId) -> None: + """Relay peer to all ready connections.""" for conn in self.iter_ready_connections(): - if conn != protocol: - assert conn.state is not None - assert isinstance(conn.state, ReadyState) - conn.state.send_peers([protocol]) + if conn.peer == peer: + continue + assert isinstance(conn.state, ReadyState) + conn.state.send_peers([peer]) def on_peer_disconnect(self, protocol: HathorProtocol) -> None: """Called when a peer disconnect.""" @@ -459,12 +466,28 @@ def on_receive_peer(self, peer: PeerId, origin: Optional[ReadyState] = None) -> peer = self.received_peer_storage.add_or_merge(peer) self.connect_to_if_not_connected(peer, int(self.reactor.seconds())) + def peers_cleanup(self) -> None: + """Clean up aged peers.""" + now = self.reactor.seconds() + to_be_removed: list[PeerId] = [] + for peer in self.peer_storage.values(): + assert peer.id is not None + if self.is_peer_connected(peer.id): + continue + dt = now - peer.last_seen + if dt > self.max_peer_unseen_dt: + to_be_removed.append(peer) + + for peer in to_be_removed: + self.peer_storage.remove(peer) + def reconnect_to_all(self) -> None: """ It is called by the `lc_reconnect` timer and tries to connect to all known peers. TODO(epnichols): Should we always connect to *all*? Should there be a max #? """ + self.peers_cleanup() # when we have no connected peers left, run the discovery process again assert self.manager is not None now = self.reactor.seconds() diff --git a/hathor/p2p/peer_id.py b/hathor/p2p/peer_id.py index 612459e7a..532502ab8 100644 --- a/hathor/p2p/peer_id.py +++ b/hathor/p2p/peer_id.py @@ -15,6 +15,7 @@ import base64 import hashlib from enum import Enum +from math import inf from typing import TYPE_CHECKING, Any, Generator, Optional, cast from cryptography import x509 @@ -61,6 +62,7 @@ class PeerId: retry_timestamp: int # should only try connecting to this peer after this timestamp retry_interval: int # how long to wait for next connection retry. It will double for each failure retry_attempts: int # how many retries were made + last_seen: float # last time this peer was seen flags: set[str] def __init__(self, auto_generate_keys: bool = True) -> None: @@ -73,6 +75,7 @@ def __init__(self, auto_generate_keys: bool = True) -> None: self.retry_timestamp = 0 self.retry_interval = 5 self.retry_attempts = 0 + self.last_seen = inf self.flags = set() self._certificate_options: Optional[CertificateOptions] = None diff --git a/hathor/p2p/protocol.py b/hathor/p2p/protocol.py index 822973bed..3df296466 100644 --- a/hathor/p2p/protocol.py +++ b/hathor/p2p/protocol.py @@ -293,7 +293,10 @@ def recv_message(self, cmd: ProtocolMessages, payload: str) -> Optional[Deferred """ assert self.state is not None - self.last_message = self.reactor.seconds() + now = self.reactor.seconds() + self.last_message = now + if self.peer is not None: + self.peer.last_seen = now self.reset_idle_timeout() if not self.ratelimit.add_hit(self.RateLimitKeys.GLOBAL): diff --git a/hathor/p2p/resources/status.py b/hathor/p2p/resources/status.py index 35a722e69..09be830ca 100644 --- a/hathor/p2p/resources/status.py +++ b/hathor/p2p/resources/status.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import time - import hathor from hathor.api_util import Resource, set_cors from hathor.cli.openapi_files.register import register_resource @@ -34,11 +32,14 @@ class StatusResource(Resource): def __init__(self, manager): self._settings = get_settings() self.manager = manager + self.reactor = manager.reactor def render_GET(self, request): request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') + now = self.reactor.seconds() + connecting_peers = [] # TODO: refactor as not to use a private item for endpoint, deferred in self.manager.connections.connecting_peers.items(): @@ -53,7 +54,7 @@ def render_GET(self, request): handshaking_peers.append({ 'address': '{}:{}'.format(remote.host, remote.port), 'state': conn.state.state_name, - 'uptime': time.time() - conn.connection_time, + 'uptime': now - conn.connection_time, 'app_version': conn.app_version, }) @@ -65,12 +66,13 @@ def render_GET(self, request): connected_peers.append({ 'id': conn.peer.id, 'app_version': conn.app_version, - 'uptime': time.time() - conn.connection_time, + 'current_time': now, + 'uptime': now - conn.connection_time, 'address': '{}:{}'.format(remote.host, remote.port), 'state': conn.state.state_name, # 'received_bytes': conn.received_bytes, 'rtt': list(conn.state.rtt_window), - 'last_message': time.time() - conn.last_message, + 'last_message': now - conn.last_message, 'plugins': status, 'warning_flags': [flag.value for flag in conn.warning_flags], 'protocol_version': str(conn.sync_version), @@ -82,6 +84,7 @@ def render_GET(self, request): known_peers.append({ 'id': peer.id, 'entrypoints': peer.entrypoints, + 'last_seen': now - peer.last_seen, 'flags': [flag.value for flag in peer.flags], }) @@ -103,7 +106,7 @@ def render_GET(self, request): 'app_version': app, 'state': self.manager.state.value, 'network': self.manager.network, - 'uptime': time.time() - self.manager.start_time, + 'uptime': now - self.manager.start_time, 'entrypoints': self.manager.connections.my_peer.entrypoints, }, 'peers_whitelist': self.manager.peers_whitelist, diff --git a/hathor/p2p/states/ready.py b/hathor/p2p/states/ready.py index a93727719..3f945ff02 100644 --- a/hathor/p2p/states/ready.py +++ b/hathor/p2p/states/ready.py @@ -47,6 +47,11 @@ def __init__(self, protocol: 'HathorProtocol') -> None: self.lc_ping = LoopingCall(self.send_ping_if_necessary) self.lc_ping.clock = self.reactor + # LC to send GET_PEERS every once in a while. + self.lc_get_peers = LoopingCall(self.send_get_peers) + self.lc_get_peers.clock = self.reactor + self.get_peers_interval: int = 5 * 60 # Once every 5 minutes. + # Minimum interval between PING messages (in seconds). self.ping_interval: int = 3 @@ -110,6 +115,8 @@ def on_enter(self) -> None: self.protocol.on_peer_ready() self.lc_ping.start(1, now=False) + + self.lc_get_peers.start(self.get_peers_interval, now=False) self.send_get_peers() if self.lc_get_best_blockchain is not None: @@ -121,6 +128,9 @@ def on_exit(self) -> None: if self.lc_ping.running: self.lc_ping.stop() + if self.lc_get_peers.running: + self.lc_get_peers.stop() + if self.lc_get_best_blockchain is not None and self.lc_get_best_blockchain.running: self.lc_get_best_blockchain.stop() @@ -146,22 +156,21 @@ def handle_get_peers(self, payload: str) -> None: """ Executed when a GET-PEERS command is received. It just responds with a list of all known peers. """ - if self.protocol.connections: - self.send_peers(self.protocol.connections.iter_ready_connections()) + for peer in self.protocol.connections.peer_storage.values(): + self.send_peers([peer]) - def send_peers(self, connections: Iterable['HathorProtocol']) -> None: - """ Send a PEERS command with a list of all connected peers. + def send_peers(self, peer_list: Iterable['PeerId']) -> None: + """ Send a PEERS command with a list of peers. """ - peers = [] - for conn in connections: - assert conn.peer is not None - peers.append({ - 'id': conn.peer.id, - 'entrypoints': conn.peer.entrypoints, - 'last_message': conn.last_message, - }) - self.send_message(ProtocolMessages.PEERS, json_dumps(peers)) - self.log.debug('send peers', peers=peers) + data = [] + for peer in peer_list: + if peer.entrypoints: + data.append({ + 'id': peer.id, + 'entrypoints': peer.entrypoints, + }) + self.send_message(ProtocolMessages.PEERS, json_dumps(data)) + self.log.debug('send peers', peers=data) def handle_peers(self, payload: str) -> None: """ Executed when a PEERS command is received. It updates the list diff --git a/hathor/p2p/sync_v1/agent.py b/hathor/p2p/sync_v1/agent.py index ce3aea322..8a53fd962 100644 --- a/hathor/p2p/sync_v1/agent.py +++ b/hathor/p2p/sync_v1/agent.py @@ -622,6 +622,14 @@ def handle_get_tips(self, payload: str) -> None: def send_tips(self, timestamp: Optional[int] = None, include_hashes: bool = False, offset: int = 0) -> None: """Try to send a TIPS message. If rate limit has been reached, it schedules to send it later.""" + + # Filter for active delayed calls once one is executing + self._send_tips_call_later = [ + call_later + for call_later in self._send_tips_call_later + if call_later.active() + ] + if not self.global_rate_limiter.add_hit(self.GlobalRateLimiter.SEND_TIPS): self.log.debug('send_tips throttled') if len(self._send_tips_call_later) >= self._settings.MAX_GET_TIPS_DELAYED_CALLS: @@ -635,18 +643,12 @@ def send_tips(self, timestamp: Optional[int] = None, include_hashes: bool = Fals ) ) return + self._send_tips(timestamp, include_hashes, offset) def _send_tips(self, timestamp: Optional[int] = None, include_hashes: bool = False, offset: int = 0) -> None: """ Send a TIPS message. """ - # Filter for active delayed calls once one is executing - self._send_tips_call_later = [ - call_later - for call_later in self._send_tips_call_later - if call_later.active() - ] - if timestamp is None: timestamp = self.manager.tx_storage.latest_timestamp diff --git a/tests/p2p/test_protocol.py b/tests/p2p/test_protocol.py index 8ce4f85b0..ae2a10a75 100644 --- a/tests/p2p/test_protocol.py +++ b/tests/p2p/test_protocol.py @@ -411,16 +411,18 @@ def test_two_connections(self): self.assertAndStepConn(self.conn, b'^GET-TIPS') self.assertAndStepConn(self.conn, b'^PING') - for _ in range(19): + for _ in range(20): self.assertAndStepConn(self.conn, b'^GET-BEST-BLOCKCHAIN') - # peer1 should now send a PEERS with the new peer that just connected - self.assertAndStepConn(self.conn, b'^PEERS', b'^GET-BEST-BLOCKCHAIN') - self.assertAndStepConn(self.conn, b'^GET-BEST-BLOCKCHAIN', b'^TIPS') - self.assertAndStepConn(self.conn, b'^TIPS', b'^TIPS') - self.assertAndStepConn(self.conn, b'^TIPS', b'^TIPS-END') - self.assertAndStepConn(self.conn, b'^TIPS-END', b'^PONG') - self.assertAndStepConn(self.conn, b'^PONG', b'^BEST-BLOCKCHAIN') + self.assertAndStepConn(self.conn, b'^GET-PEERS', b'^GET-PEERS') + self.assertAndStepConn(self.conn, b'^GET-BEST-BLOCKCHAIN', b'^GET-BEST-BLOCKCHAIN') + self.assertAndStepConn(self.conn, b'^GET-PEERS', b'^GET-PEERS') + self.assertAndStepConn(self.conn, b'^PEERS', b'^GET-BEST-BLOCKCHAIN') + self.assertAndStepConn(self.conn, b'^GET-BEST-BLOCKCHAIN', b'^TIPS') + self.assertAndStepConn(self.conn, b'^TIPS', b'^TIPS') + self.assertAndStepConn(self.conn, b'^TIPS', b'^TIPS-END') + self.assertAndStepConn(self.conn, b'^TIPS-END', b'^PONG') + self.assertAndStepConn(self.conn, b'^PONG', b'^BEST-BLOCKCHAIN') self.assertIsConnected() @inlineCallbacks