From d862f01404da0ea851e793009cf1197d5a385fcc Mon Sep 17 00:00:00 2001 From: Marcelo Salhab Brogliato Date: Fri, 10 May 2024 11:19:02 -0500 Subject: [PATCH] feat(cli): Add load_from_logs cli command to load blocks and transactions as they are found in a log dump --- hathor/cli/load_from_logs.py | 65 ++++++++++++++++++++++++++++++++++++ hathor/cli/main.py | 2 ++ 2 files changed, 67 insertions(+) create mode 100644 hathor/cli/load_from_logs.py diff --git a/hathor/cli/load_from_logs.py b/hathor/cli/load_from_logs.py new file mode 100644 index 000000000..c5a34e427 --- /dev/null +++ b/hathor/cli/load_from_logs.py @@ -0,0 +1,65 @@ +# Copyright 2024 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. + +import re +import sys +from argparse import ArgumentParser, FileType + +from hathor.cli.run_node import RunNode + + +class LoadFromLogs(RunNode): + def start_manager(self) -> None: + pass + + def register_signal_handlers(self) -> None: + pass + + @classmethod + def create_parser(cls) -> ArgumentParser: + parser = super().create_parser() + parser.add_argument('--log-dump', type=FileType('r', encoding='UTF-8'), default=sys.stdin, nargs='?', + help='Where to read logs from, defaults to stdin.') + return parser + + def prepare(self, *, register_resources: bool = True) -> None: + super().prepare(register_resources=False) + + def run(self) -> None: + from hathor.transaction.base_transaction import tx_or_block_from_bytes + + pattern = r'new (tx|block) .*bytes=([^ ]*) ' + pattern = r'new (tx|block) .*bytes=([^ ]*) ' + compiled_pattern = re.compile(pattern) + + while True: + line_with_break = self._args.log_dump.readline() + if not line_with_break: + break + line = line_with_break.strip() + + matches = compiled_pattern.findall(line) + if len(matches) == 0: + continue + + assert len(matches) == 1 + _, vertex_bytes_hex = matches[0] + + vertex_bytes = bytes.fromhex(vertex_bytes_hex) + vertex = tx_or_block_from_bytes(vertex_bytes) + self.manager.on_new_tx(vertex) + + +def main(): + LoadFromLogs().run() diff --git a/hathor/cli/main.py b/hathor/cli/main.py index a1ab960d2..6c4c84f4e 100644 --- a/hathor/cli/main.py +++ b/hathor/cli/main.py @@ -35,6 +35,7 @@ def __init__(self) -> None: db_export, db_import, generate_valid_words, + load_from_logs, merged_mining, mining, multisig_address, @@ -91,6 +92,7 @@ def __init__(self) -> None: self.add_cmd('dev', 'x-export', db_export, 'EXPERIMENTAL: Export database to a simple format.') self.add_cmd('dev', 'x-import', db_import, 'EXPERIMENTAL: Import database from exported format.') self.add_cmd('dev', 'replay-logs', replay_logs, 'EXPERIMENTAL: re-play json logs as console printted') + self.add_cmd('dev', 'load-from-logs', load_from_logs, 'Load vertices as they are found in a log dump') def add_cmd(self, group: str, cmd: str, module: ModuleType, short_description: Optional[str] = None) -> None: self.command_list[cmd] = module