From 1a6087b2d134f5854485514b5e206616554ea4a5 Mon Sep 17 00:00:00 2001 From: Sean Darcy Date: Thu, 16 Mar 2023 12:58:13 +1100 Subject: [PATCH] statusbar to command line --- .../cli-wallet/oxen_wallet_cli/walletcli.py | 45 ++++++++++++++++++- src/wallet3/cli-wallet/pyproject.toml | 1 + src/wallet3/db_schema.cpp | 6 +++ src/wallet3/db_schema.hpp | 4 ++ src/wallet3/rpc/commands.h | 18 +++++++- src/wallet3/rpc/request_handler.cpp | 20 +++++++-- src/wallet3/rpc/request_handler.h | 2 +- 7 files changed, 90 insertions(+), 6 deletions(-) diff --git a/src/wallet3/cli-wallet/oxen_wallet_cli/walletcli.py b/src/wallet3/cli-wallet/oxen_wallet_cli/walletcli.py index 877b55312..cddd9f0e4 100644 --- a/src/wallet3/cli-wallet/oxen_wallet_cli/walletcli.py +++ b/src/wallet3/cli-wallet/oxen_wallet_cli/walletcli.py @@ -1,9 +1,12 @@ import os from pathlib import Path +import time import click import click_repl +from tqdm import tqdm + from oxen_wallet_cli import context import pywallet3 @@ -42,6 +45,34 @@ def walletcli(click_ctx, **options): click.echo("Run 'help' for help information, or 'quit' to quit.") click_repl.repl(click_ctx) +def progress_bar(): + click.echo("Starting Wallet Sync") + with tqdm(total=1, ncols = 80, nrows = 3, position = 0, leave=False, unit="blocks", colour="green") as pbar: + syncing = True + retries = 10 + prev_height = 0 + while syncing and retries > 0: + try: + status_future = context.rpc_future("rpc.status"); + status_response = status_future.get(); + pbar.total = status_response["target_height"] + pbar.update(status_response["sync_height"] - prev_height) + prev_height = status_response["sync_height"] + syncing = status_response["syncing"] + time.sleep(0.5) + except Excepiton as e: + retries -= 1 + click.echo("Wallet Synced") + pbar.close() + +def display_status(): + status_future = context.rpc_future("rpc.status"); + status_response = status_future.get(); + if status_response["syncing"]: + progress_bar() + else: + click.echo("Wallet Synced") + @walletcli.command() def load_test_wallet(): click.echo("Loading test wallet") @@ -55,7 +86,7 @@ def load_test_wallet(): view_pub = "8a0ebacd613e0b03b8f27bc64bd961ea2ebf4c671c6e7f3268651acf0823fed5" keyring = pywallet3.Keyring(spend_priv, spend_pub, view_priv, view_pub, context.options["network"]) - click.echo("Wallet address {} loaded".format(keyring.get_main_address())) + click.echo("Wallet address " + click.style("{}", fg='cyan', bold=True).format(keyring.get_main_address()) + " loaded") if context.options['wallet_name'] is None: name = click.prompt("Wallet Name", default="{}-oxen-wallet".format(context.options["network"])).strip() else: @@ -63,6 +94,7 @@ def load_test_wallet(): context.wallet_core_config.omq_rpc.sockname = name + ".sock"; context.wallet = pywallet3.Wallet(name, keyring, context.wallet_core_config) context.omq_connection() + display_status() @walletcli.command() @click.argument('seed_phrase', nargs=25) @@ -83,6 +115,7 @@ def load_from_seed(seed_phrase, seed_phrase_passphrase): context.wallet_core_config.omq_rpc.sockname = name + ".sock"; context.wallet = pywallet3.Wallet(name, keyring, context.wallet_core_config) context.omq_connection() + display_status() @walletcli.command() def load_from_file(): @@ -99,6 +132,7 @@ def load_from_file(): context.wallet_core_config.omq_rpc.sockname = name + ".sock"; context.wallet = pywallet3.Wallet(name, keyring, context.wallet_core_config) context.omq_connection() + display_status() @walletcli.command() def register_service_node(): @@ -109,6 +143,15 @@ def register_service_node(): click.echo("The wallet address to be used is: {}".format(name)) click.echo("TODO: This function is not yet implemented") +@walletcli.command() +def status(): + if context.wallet is None: + click.echo("Wallet not loaded") + return + status_future = context.rpc_future("rpc.status"); + status_response = status_future.get(); + click.echo("Status: {}".format(status_response)) + @walletcli.command() def address(): if context.wallet is None: diff --git a/src/wallet3/cli-wallet/pyproject.toml b/src/wallet3/cli-wallet/pyproject.toml index 3b5497ade..1503f98d0 100644 --- a/src/wallet3/cli-wallet/pyproject.toml +++ b/src/wallet3/cli-wallet/pyproject.toml @@ -23,6 +23,7 @@ dependencies = [ "Click", "click-repl", "pywallet3", + "tqdm", ] dynamic = ["version"] diff --git a/src/wallet3/db_schema.cpp b/src/wallet3/db_schema.cpp index d5d7387b9..391875d6f 100644 --- a/src/wallet3/db_schema.cpp +++ b/src/wallet3/db_schema.cpp @@ -401,6 +401,12 @@ namespace wallet return get_metadata_int("scan_target_height"); } + int64_t + WalletDB::current_height() + { + return prepared_get("SELECT max(height) from blocks;"); + } + void WalletDB::update_top_block_info(int64_t height, const crypto::hash& hash) { diff --git a/src/wallet3/db_schema.hpp b/src/wallet3/db_schema.hpp index d56aa9d04..b90abc565 100644 --- a/src/wallet3/db_schema.hpp +++ b/src/wallet3/db_schema.hpp @@ -85,6 +85,10 @@ namespace wallet int64_t scan_target_height(); + // Returns the height of the highest block in the database + int64_t + current_height(); + // Update the top block height and hash. void update_top_block_info(int64_t height, const crypto::hash& hash); diff --git a/src/wallet3/rpc/commands.h b/src/wallet3/rpc/commands.h index 5417e5b9b..a70a6d07c 100644 --- a/src/wallet3/rpc/commands.h +++ b/src/wallet3/rpc/commands.h @@ -203,6 +203,21 @@ namespace wallet::rpc { } request; }; + OXEN_RPC_DOC_INTROSPECT + /// Returns the status of the wallet + /// + /// Inputs: No Inputs + /// + /// Outputs: + /// + /// - \p syncing -- True/False if the wallet is still syncing + /// - \p sync_height -- Current Height of Wallet + /// - \p target_height -- Desired Height of the Wallet + struct STATUS : NO_ARGS + { + static constexpr auto names() { return NAMES("status"); } + }; + OXEN_RPC_DOC_INTROSPECT /// Label an address. /// @@ -2914,7 +2929,8 @@ This command is only required if the open wallet is one of the owners of a ONS r ONS_KNOWN_NAMES, ONS_ADD_KNOWN_NAMES, ONS_DECRYPT_VALUE, - ONS_ENCRYPT_VALUE + ONS_ENCRYPT_VALUE, + STATUS >; } diff --git a/src/wallet3/rpc/request_handler.cpp b/src/wallet3/rpc/request_handler.cpp index 8e3822201..19e259671 100644 --- a/src/wallet3/rpc/request_handler.cpp +++ b/src/wallet3/rpc/request_handler.cpp @@ -150,11 +150,12 @@ void RequestHandler::invoke(SET_ACCOUNT_TAG_DESCRIPTION& command, rpc_context co void RequestHandler::invoke(GET_HEIGHT& command, rpc_context context) { if (auto w = wallet.lock()) { - auto height = w->db->scan_target_height(); + const auto immutable_height = w->db->scan_target_height(); + const auto height = w->db->current_height(); + command.response["height"] = height; - //TODO: this - command.response["immutable_height"] = height; + command.response["immutable_height"] = immutable_height; } } @@ -559,5 +560,18 @@ void RequestHandler::invoke(ONS_ENCRYPT_VALUE& command, rpc_context context) { void RequestHandler::invoke(ONS_DECRYPT_VALUE& command, rpc_context context) { } +void RequestHandler::invoke(STATUS& command, rpc_context context) { + if (auto w = wallet.lock()) + { + const auto sync_height = w->db->current_height(); + const auto target_height = w->db->scan_target_height(); + + command.response["sync_height"] = sync_height; + command.response["target_height"] = target_height; + + command.response["syncing"] = sync_height < target_height; + } +} + } // namespace wallet::rpc diff --git a/src/wallet3/rpc/request_handler.h b/src/wallet3/rpc/request_handler.h index e54932249..931d26668 100644 --- a/src/wallet3/rpc/request_handler.h +++ b/src/wallet3/rpc/request_handler.h @@ -16,7 +16,6 @@ namespace wallet { class Wallet; } - namespace wallet::rpc { class RequestHandler; @@ -149,6 +148,7 @@ public: void invoke(ONS_ADD_KNOWN_NAMES& command, rpc_context context); void invoke(ONS_ENCRYPT_VALUE& command, rpc_context context); void invoke(ONS_DECRYPT_VALUE& command, rpc_context context); + void invoke(STATUS& command, rpc_context context); };