diff --git a/modules/alert_bot.py b/modules/alert_bot.py index 2e16e504..b9f99012 100644 --- a/modules/alert_bot.py +++ b/modules/alert_bot.py @@ -5,6 +5,7 @@ from modules.module import MtcModule from mypylib.mypylib import get_timestamp, print_table, color_print from mytoncore import get_hostname, signed_int_to_hex64 +from mytonctrl.console_cmd import add_command, check_usage_one_arg, check_usage_two_args from mytonctrl.utils import timestamp2utcdatetime @@ -333,15 +334,15 @@ def _is_alert_active(self, alert_name: str) -> bool: return self.get_alert_from_db(alert_name).get('active', False) def enable_alert(self, args): - if len(args) != 1: - raise Exception("Usage: enable_alert ") + if not check_usage_one_arg("enable_alert", args): + return alert_name = args[0] self.set_alert_enabled(alert_name, True) color_print("enable_alert - {green}OK{endc}") def disable_alert(self, args): - if len(args) != 1: - raise Exception("Usage: disable_alert ") + if not check_usage_one_arg("disable_alert", args): + return alert_name = args[0] self.set_alert_enabled(alert_name, False) color_print("disable_alert - {green}OK{endc}") @@ -360,8 +361,8 @@ def test_alert(self, args): self.send_message('Test alert') def setup_alert_bot(self, args): - if len(args) != 2: - raise Exception("Usage: setup_alert_bot ") + if not check_usage_two_args("setup_alert_bot", args): + return self.token = args[0] self.chat_id = args[1] init_alerts() @@ -602,8 +603,8 @@ def check_status(self): self.local.try_function(self.check_online_collators) def add_console_commands(self, console): - console.AddItem("enable_alert", self.enable_alert, self.local.translate("enable_alert_cmd")) - console.AddItem("disable_alert", self.disable_alert, self.local.translate("disable_alert_cmd")) - console.AddItem("list_alerts", self.print_alerts, self.local.translate("list_alerts_cmd")) - console.AddItem("test_alert", self.test_alert, self.local.translate("test_alert_cmd")) - console.AddItem("setup_alert_bot", self.setup_alert_bot, self.local.translate("setup_alert_bot_cmd")) + add_command(self.local, console, "enable_alert", self.enable_alert) + add_command(self.local, console, "disable_alert", self.disable_alert) + add_command(self.local, console, "list_alerts", self.print_alerts) + add_command(self.local, console, "test_alert", self.test_alert) + add_command(self.local, console, "setup_alert_bot", self.setup_alert_bot) diff --git a/modules/backups.py b/modules/backups.py index 120b00aa..e6f25558 100644 --- a/modules/backups.py +++ b/modules/backups.py @@ -6,6 +6,7 @@ from typing import Optional from modules.module import MtcModule +from mytonctrl.console_cmd import add_command, check_usage_two_args, check_usage_args_min_max_len from mypylib.mypylib import color_print, ip2int, run_as_root, parse from mytoncore.utils import get_package_resource_path from mytonctrl.utils import get_current_user, pop_user_from_args @@ -38,10 +39,9 @@ def run_create_backup(args, user: Optional[str] = None): with get_package_resource_path('mytonctrl', 'scripts/create_backup.sh') as backup_script_path: return subprocess.run(["bash", backup_script_path, "-u", user] + args, timeout=5) - def create_backup(self, args: list) -> typing.Union[int, None]: - if len(args) > 3: - color_print("{red}Bad args. Usage:{endc} create_backup [filename] [-u ]") - return None + def create_backup(self, args): + if not check_usage_args_min_max_len("create_backup", args, 0, 3): + return tmp_dir = self.create_tmp_ton_dir() command_args = ["-m", self.ton.local.buffer.my_work_dir, "-t", tmp_dir] user = pop_user_from_args(args) @@ -64,8 +64,7 @@ def run_restore_backup(args, user: Optional[str] = None): return run_as_root(["bash", restore_script_path, "-u", user] + args) def restore_backup(self, args): - if len(args) == 0 or len(args) > 5: - color_print("{red}Bad args. Usage:{endc} restore_backup [-y] [--skip-create-backup] [-u ]") + if not check_usage_args_min_max_len('restore_backup', args, 1, 5): return user = pop_user_from_args(args) if '-y' not in args: @@ -99,5 +98,5 @@ def restore_backup(self, args): color_print("restore_backup - {red}Error{endc}") def add_console_commands(self, console): - console.AddItem("create_backup", self.create_backup, self.local.translate("create_backup_cmd")) - console.AddItem("restore_backup", self.restore_backup, self.local.translate("restore_backup_cmd")) + add_command(self.local, console, "create_backup", self.create_backup) + add_command(self.local, console, "restore_backup", self.restore_backup) diff --git a/modules/btc_teleport.py b/modules/btc_teleport.py index fce1dd49..8b64c872 100644 --- a/modules/btc_teleport.py +++ b/modules/btc_teleport.py @@ -3,7 +3,9 @@ from typing import Optional from modules.module import MtcModule -from mypylib.mypylib import run_as_root, color_print + +from mytonctrl.console_cmd import add_command, check_usage_args_min_max_len +from mypylib.mypylib import run_as_root from mytoncore.utils import get_package_resource_path from mytonctrl.utils import get_current_user @@ -91,8 +93,7 @@ def run_remove_btc_teleport(args): return run_as_root(["bash", script_path] + args) def remove_btc_teleport(self, args: list): - if len(args) > 1: - color_print("{red}Bad args. Usage:{endc} remove_btc_teleport [--force]") + if not check_usage_args_min_max_len("remove_btc_teleport", args, min_len=0, max_len=1): return if '--force' not in args: if -1 < self.ton.GetValidatorIndex() < self.ton.GetConfig34()['mainValidators']: @@ -104,4 +105,4 @@ def remove_btc_teleport(self, args: list): self.local.add_log('Removed btc_teleport', 'info') def add_console_commands(self, console): - console.AddItem("remove_btc_teleport", self.remove_btc_teleport, self.local.translate("remove_btc_teleport_cmd")) + add_command(self.local, console, "remove_btc_teleport", self.remove_btc_teleport) diff --git a/modules/collator.py b/modules/collator.py index dbcc2aed..fb04e86d 100644 --- a/modules/collator.py +++ b/modules/collator.py @@ -1,6 +1,7 @@ from modules.module import MtcModule from mypylib import color_print, print_table from mytoncore import b642hex, signed_int_to_hex64, shard_prefix_len, hex_shard_to_int, shard_prefix, shard_is_ancestor +from mytonctrl.console_cmd import check_usage_args_min_len, add_command, check_usage_no_args, check_usage_args_lens from mytonctrl.utils import pop_arg_from_args @@ -44,9 +45,7 @@ def _check_input_shards(node_shards: list, shards_need_to_add: list, monitor_min def setup_collator(self, args: list): from mytoninstaller.mytoninstaller import set_node_argument from mytoninstaller.node_args import get_node_args - - if not args: - color_print("{red}Bad args. Usage:{endc} setup_collator [--force] [--adnl ] [shard2] ...") + if not check_usage_args_min_len("setup_collator", args, 1): return force = '--force' in args args.remove('--force') if '--force' in args else None @@ -81,6 +80,8 @@ def setup_collator(self, args: list): color_print("setup_collator - {green}OK{endc}") def stop_collator(self, args: list): + if not check_usage_args_lens("stop_collator", args, [0, 2]): + return if not args: text = f"{{red}}WARNING: This action will stop and delete all local collation broadcasts from this node for all shards.{{endc}}\n" color_print(text) @@ -104,17 +105,12 @@ def stop_collator(self, args: list): color_print("stop_collator - {green}OK{endc}") return - if len(args) == 2: - adnl_addr, shard_str = args - if ':' not in shard_str: - color_print("{red}Bad args. Usage:{endc} stop_collator :") - return - shard_id = hex_shard_to_int(shard_str) - workchain = int(shard_id['workchain']) - shard_int = int(shard_id['shard']) - else: - color_print("{red}Bad args. Usage:{endc} stop_collator :") - return + adnl_addr, shard_str = args + if ':' not in shard_str: + raise Exception(f"Invalid shard: {shard_str}, use format :") + shard_id = hex_shard_to_int(shard_str) + workchain = int(shard_id['workchain']) + shard_int = int(shard_id['shard']) res = self.ton.validatorConsole.Run(f"del-collator {adnl_addr} {workchain} {shard_int}") if 'successfully removed collator' not in res.lower(): @@ -136,8 +132,7 @@ def print_collators(self, args: list = None): print_table(table) def add_validator_to_collation_wl(self, args: list): - if len(args) < 1: - color_print("{red}Bad args. Usage:{endc} add_validator_to_collation_wl [adnl2] [adnl3] ...") + if not check_usage_args_min_len("add_validator_to_collation_wl", args, 1): return self.ton.validatorConsole.Run(f"collator-whitelist-enable 1") self.local.add_log("Collation whitelist enabled") @@ -148,8 +143,7 @@ def add_validator_to_collation_wl(self, args: list): color_print("add_validator_to_collation_wl - {green}OK{endc}") def delete_validator_from_collation_wl(self, args: list): - if len(args) < 1: - color_print("{red}Bad args. Usage:{endc} delete_validator_from_collation_wl [adnl2] [adnl3] ...") + if not check_usage_args_min_len("delete_validator_from_collation_wl", args, 1): return for adnl_addr in args: result = self.ton.validatorConsole.Run(f"collator-whitelist-del {adnl_addr}") @@ -158,8 +152,7 @@ def delete_validator_from_collation_wl(self, args: list): color_print("delete_validator_from_collation_wl - {green}OK{endc}") def disable_collation_validator_wl(self, args: list): - if len(args) != 0: - color_print("{red}Bad args. Usage:{endc} disable_collation_validator_wl") + if not check_usage_no_args("disable_collation_wl", args): return result = self.ton.validatorConsole.Run(f"collator-whitelist-enable 0") if 'success' not in result: @@ -186,10 +179,10 @@ def check_disable(self): def add_console_commands(self, console): - console.AddItem("setup_collator", self.setup_collator, self.local.translate("setup_collator_cmd")) - console.AddItem("print_local_collators", self.print_collators, self.local.translate("print_local_collators_cmd")) - console.AddItem("add_validator_to_collation_wl", self.add_validator_to_collation_wl, self.local.translate("add_validator_to_collation_wl_cmd")) - console.AddItem("delete_validator_from_collation_wl", self.delete_validator_from_collation_wl, self.local.translate("delete_validator_from_collation_wl_cmd")) - console.AddItem("disable_collation_wl", self.disable_collation_validator_wl, self.local.translate("disable_collation_validator_wl_cmd")) - console.AddItem("print_collation_whitelist", self.print_collation_validators_whitelist, self.local.translate("print_collation_validators_whitelist_cmd")) - console.AddItem("stop_collator", self.stop_collator, self.local.translate("stop_collator_cmd")) + add_command(self.local, console, "setup_collator", self.setup_collator) + add_command(self.local, console, "print_local_collators", self.print_collators) + add_command(self.local, console, "add_validator_to_collation_wl", self.add_validator_to_collation_wl) + add_command(self.local, console, "delete_validator_from_collation_wl", self.delete_validator_from_collation_wl) + add_command(self.local, console, "disable_collation_wl", self.disable_collation_validator_wl) + add_command(self.local, console, "print_collation_whitelist", self.print_collation_validators_whitelist) + add_command(self.local, console, "stop_collator", self.stop_collator) diff --git a/modules/collator_config.py b/modules/collator_config.py index 0ece5338..a648c38d 100644 --- a/modules/collator_config.py +++ b/modules/collator_config.py @@ -3,6 +3,7 @@ from mypylib.mypylib import color_print from modules.module import MtcModule +from mytonctrl.console_cmd import add_command, check_usage_one_arg class CollatorConfigModule(MtcModule): @@ -47,15 +48,14 @@ def add_collator_config_to_vc(self, config: dict): return 'success' in result, result def set_collator_config(self, args): - if len(args) != 1: - color_print("{red}Bad args. Usage:{endc} set_collator_config ") + if not check_usage_one_arg("set_collation_config", args): return location = args[0] config = self.get_config(location) self.ton.set_collator_config(location) added, msg = self.add_collator_config_to_vc(config) if not added: - print(f'Failed to add collator config to validator console: {msg}') + print(f'Failed to add collation config to validator console: {msg}') color_print("set_collator_config - {red}ERROR{endc}") return color_print("set_collator_config - {green}OK{endc}") @@ -86,6 +86,6 @@ def update_collator_config(self, args): color_print("update_collator_config - {green}OK{endc}") def add_console_commands(self, console): - console.AddItem("set_collation_config", self.set_collator_config, self.local.translate("set_collation_config_cmd")) - console.AddItem("update_collation_config", self.update_collator_config, self.local.translate("update_collation_config_cmd")) - console.AddItem("print_collation_config", self.get_collator_config, self.local.translate("print_collation_config_cmd")) + add_command(self.local, console, "set_collation_config", self.set_collator_config) + add_command(self.local, console, "update_collation_config", self.update_collator_config) + add_command(self.local, console, "print_collation_config", self.get_collator_config) diff --git a/modules/controller.py b/modules/controller.py index 2f39084f..30ff1b30 100644 --- a/modules/controller.py +++ b/modules/controller.py @@ -3,6 +3,7 @@ import time from mypylib.mypylib import color_print, print_table +from mytonctrl.console_cmd import add_command, check_usage_one_arg, check_usage_two_args, check_usage_args_min_max_len from mytonctrl.utils import GetItemFromList from modules.module import MtcModule @@ -75,11 +76,9 @@ def print_controllers_list_process(self, controllers): print_table(table) def get_controller_data(self, args): - try: - controller_addr = args[0] - except: - color_print("{red}Bad args. Usage:{endc} get_controller_data ") + if not check_usage_one_arg("get_controller_data", args): return + controller_addr = args[0] controller_data = self.ton.GetControllerData(controller_addr) print(json.dumps(controller_data, indent=4)) @@ -91,27 +90,25 @@ def do_deposit_to_controller(self, controller_addr, amount): self.ton.SendFile(result_file_path, wallet) def deposit_to_controller(self, args): - try: - controller_addr = args[0] - amount = float(args[1]) - except: - color_print("{red}Bad args. Usage:{endc} deposit_to_controller ") + if not check_usage_two_args("deposit_to_controller", args): return + controller_addr = args[0] + amount = float(args[1]) self.do_deposit_to_controller(controller_addr, amount) def withdraw_from_controller(self, args): - try: - controller_addr = args[0] - amount = GetItemFromList(args, 1) - except: - color_print("{red}Bad args. Usage:{endc} withdraw_from_controller [amount]") + if not check_usage_args_min_max_len("withdraw_from_controller", args, min_len=1, max_len=2): return + controller_addr = args[0] + amount = GetItemFromList(args, 1) self.ton.WithdrawFromController(controller_addr, amount) def calculate_annual_controller_percentage(self, args): - try: + if not check_usage_args_min_max_len("calculate_annual_controller_percentage", args, min_len=0, max_len=1): + return + if args: percent_per_round = float(args[0]) - except: + else: percent_per_round = self.ton.GetSettings("max_interest_percent") config15 = self.ton.GetConfig(15) roundPeriod = config15["validators_elected_for"] @@ -125,11 +122,9 @@ def calculate_annual_controller_percentage(self, args): print(f"yearInterestPercent: {yearInterestPercent}%") def controller_update_validator_set(self, args): - try: - controller_addr = args[0] - except: - color_print("{red}Bad args. Usage:{endc} controller_update_validator_set ") + if not check_usage_one_arg("controller_update_validator_set", args): return + controller_addr = args[0] self.ton.ControllerUpdateValidatorSet(controller_addr) color_print("ControllerUpdateValidatorSet - {green}OK{endc}") @@ -147,21 +142,17 @@ def do_stop_controller(self, controller_addr): self.ton.local.save() def stop_controller(self, args): - try: - controller_addr = args[0] - except: - color_print("{red}Bad args. Usage:{endc} stop_controller ") + if not check_usage_one_arg("stop_controller", args): return + controller_addr = args[0] self.do_stop_controller(controller_addr) color_print("StopController - {green}OK{endc}") def stop_and_withdraw_controller(self, args): - try: - controller_addr = args[0] - amount = GetItemFromList(args, 1) - except: - color_print("{red}Bad args. Usage:{endc} stop_and_withdraw_controller [amount]") + if not check_usage_args_min_max_len("stop_and_withdraw_controller", args, min_len=1, max_len=2): return + controller_addr = args[0] + amount = GetItemFromList(args, 1) if amount is None: account = self.ton.GetAccount(controller_addr) amount = account.balance - 10.1 @@ -183,11 +174,9 @@ def do_add_controller(self, controller_addr): self.ton.local.save() def add_controller(self, args): - try: - controller_addr = args[0] - except: - color_print("{red}Bad args. Usage:{endc} add_controller ") + if not check_usage_one_arg("add_controller", args): return + controller_addr = args[0] self.do_add_controller(controller_addr) color_print("AddController - {green}OK{endc}") @@ -238,16 +227,16 @@ def check_enable(cls, ton: "MyTonCore"): enable_ton_http_api(ton.local) def add_console_commands(self, console): - console.AddItem("create_controllers", self.create_controllers, self.local.translate("_")) - console.AddItem("update_controllers", self.create_controllers, self.local.translate("_")) - console.AddItem("controllers_list", self.print_controllers_list, self.local.translate("_")) - console.AddItem("get_controller_data", self.get_controller_data, self.local.translate("_")) - console.AddItem("deposit_to_controller", self.deposit_to_controller, self.local.translate("_")) - console.AddItem("withdraw_from_controller", self.withdraw_from_controller, self.local.translate("_")) - console.AddItem("calculate_annual_controller_percentage", self.calculate_annual_controller_percentage, self.local.translate("_")) - console.AddItem("controller_update_validator_set", self.controller_update_validator_set, self.local.translate("_")) - console.AddItem("stop_controller", self.stop_controller, self.local.translate("_")) - console.AddItem("stop_and_withdraw_controller", self.stop_and_withdraw_controller, self.local.translate("_")) - console.AddItem("add_controller", self.add_controller, self.local.translate("_")) - console.AddItem("check_liquid_pool", self.check_liquid_pool, self.local.translate("_")) - console.AddItem("test_calculate_loan_amount", self.calculate_loan_amount_test, self.local.translate("_")) + add_command(self.local, console, "create_controllers", self.create_controllers) + add_command(self.local, console, "update_controllers", self.create_controllers) + add_command(self.local, console, "controllers_list", self.print_controllers_list) + add_command(self.local, console, "get_controller_data", self.get_controller_data) + add_command(self.local, console, "deposit_to_controller", self.deposit_to_controller) + add_command(self.local, console, "withdraw_from_controller", self.withdraw_from_controller) + add_command(self.local, console, "calculate_annual_controller_percentage", self.calculate_annual_controller_percentage) + add_command(self.local, console, "controller_update_validator_set", self.controller_update_validator_set) + add_command(self.local, console, "stop_controller", self.stop_controller) + add_command(self.local, console, "stop_and_withdraw_controller", self.stop_and_withdraw_controller) + add_command(self.local, console, "add_controller", self.add_controller) + add_command(self.local, console, "check_liquid_pool", self.check_liquid_pool) + add_command(self.local, console, "test_calculate_loan_amount", self.calculate_loan_amount_test) diff --git a/modules/custom_overlays.py b/modules/custom_overlays.py index efa82dd8..857e05e9 100644 --- a/modules/custom_overlays.py +++ b/modules/custom_overlays.py @@ -4,6 +4,7 @@ from mypylib.mypylib import color_print from modules.module import MtcModule from mytoncore.utils import hex2base64 +from mytonctrl.console_cmd import add_command, check_usage_two_args, check_usage_one_arg class CustomOverlayModule(MtcModule): @@ -48,8 +49,7 @@ def parse_config(name: str, config: dict, vset: list = None): return result def add_custom_overlay(self, args): - if len(args) != 2: - color_print("{red}Bad args. Usage:{endc} add_custom_overlay ") + if not check_usage_two_args("add_custom_overlay", args): return path = args[1] with open(path, 'r') as f: @@ -74,8 +74,7 @@ def list_custom_overlays(self, args): print(json.dumps(v, indent=4)) def delete_custom_overlay(self, args): - if len(args) != 1: - color_print("{red}Bad args. Usage:{endc} delete_custom_overlay ") + if not check_usage_one_arg("delete_custom_overlay", args): return if '@validators' in self.ton.get_custom_overlays().get(args[0], {}): self.ton.delete_custom_overlay(args[0]) @@ -184,6 +183,6 @@ def get_default_custom_overlay(self): return config.get(network) def add_console_commands(self, console): - console.AddItem("add_custom_overlay", self.add_custom_overlay, self.local.translate("add_custom_overlay_cmd")) - console.AddItem("list_custom_overlays", self.list_custom_overlays, self.local.translate("list_custom_overlays_cmd")) - console.AddItem("delete_custom_overlay", self.delete_custom_overlay, self.local.translate("delete_custom_overlay_cmd")) + add_command(self.local, console, "add_custom_overlay", self.add_custom_overlay) + add_command(self.local, console, "list_custom_overlays", self.list_custom_overlays) + add_command(self.local, console, "delete_custom_overlay", self.delete_custom_overlay) diff --git a/modules/nominator_pool.py b/modules/nominator_pool.py index d00708b0..e7805e1a 100644 --- a/modules/nominator_pool.py +++ b/modules/nominator_pool.py @@ -1,8 +1,8 @@ import os -import time from mypylib.mypylib import color_print from modules.pool import PoolModule +from mytonctrl.console_cmd import add_command, check_usage_one_arg, check_usage_two_args, check_usage_args_len class NominatorPoolModule(PoolModule): @@ -38,18 +38,18 @@ def do_create_pool(self, pool_name, validator_reward_share_percent, max_nominato if pool.name != new_pool.name and pool.addrB64 == new_pool.addrB64: new_pool.Delete() raise Exception("CreatePool error: Pool with the same parameters already exists.") - # end for - # end define def new_pool(self, args): + if not check_usage_args_len("new_pool", args, 5): + return + pool_name = args[0] try: - pool_name = args[0] validator_reward_share_percent = float(args[1]) max_nominators_count = int(args[2]) min_validator_stake = int(args[3]) min_nominator_stake = int(args[4]) - except: - color_print("{red}Bad args. Usage:{endc} new_pool ") + except ValueError: + color_print("{red}Bad args types. validator_reward_share_percent=float, counts/stakes=int{endc}") return self.do_create_pool(pool_name, validator_reward_share_percent, max_nominators_count, min_validator_stake, min_nominator_stake) color_print("NewPool - {green}OK{endc}") @@ -68,21 +68,17 @@ def do_activate_pool(self, pool, ex=True): #end define def activate_pool(self, args): - try: - pool_name = args[0] - except: - color_print("{red}Bad args. Usage:{endc} activate_pool ") + if not check_usage_one_arg("activate_pool", args): return + pool_name = args[0] pool = self.ton.GetLocalPool(pool_name) self.do_activate_pool(pool) color_print("ActivatePool - {green}OK{endc}") def update_validator_set(self, args): - try: - pool_addr = args[0] - except: - color_print("{red}Bad args. Usage:{endc} update_validator_set ") + if not check_usage_one_arg("update_validator_set", args): return + pool_addr = args[0] wallet = self.ton.GetValidatorWallet() self.ton.PoolUpdateValidatorSet(pool_addr, wallet) color_print("UpdateValidatorSet - {green}OK{endc}") @@ -97,13 +93,15 @@ def do_deposit_to_pool(self, pool_addr, amount): self.ton.SendFile(resultFilePath, wallet) def deposit_to_pool(self, args): + if not check_usage_two_args("deposit_to_pool", args): + return + pool_addr = args[0] try: - poll_addr = args[0] amount = float(args[1]) - except: - color_print("{red}Bad args. Usage:{endc} deposit_to_pool ") + except ValueError: + color_print("{red}Amount must be a number{endc}") return - self.do_deposit_to_pool(poll_addr, amount) + self.do_deposit_to_pool(pool_addr, amount) color_print("DepositToPool - {green}OK{endc}") def do_withdraw_from_pool(self, pool_addr, amount): @@ -114,18 +112,20 @@ def do_withdraw_from_pool(self, pool_addr, amount): self.ton.PendWithdrawFromPool(pool_addr, amount) def withdraw_from_pool(self, args): + if not check_usage_two_args("withdraw_from_pool", args): + return + pool_addr = args[0] try: - pool_addr = args[0] amount = float(args[1]) - except: - color_print("{red}Bad args. Usage:{endc} withdraw_from_pool ") + except ValueError: + color_print("{red}Amount must be a number{endc}") return self.do_withdraw_from_pool(pool_addr, amount) color_print("WithdrawFromPool - {green}OK{endc}") def add_console_commands(self, console): - console.AddItem("new_pool", self.new_pool, self.local.translate("new_pool_cmd")) - console.AddItem("activate_pool", self.activate_pool, self.local.translate("activate_pool_cmd")) - console.AddItem("update_validator_set", self.update_validator_set, self.local.translate("update_validator_set_cmd")) - console.AddItem("withdraw_from_pool", self.withdraw_from_pool, self.local.translate("withdraw_from_pool_cmd")) - console.AddItem("deposit_to_pool", self.deposit_to_pool, self.local.translate("deposit_to_pool_cmd")) + add_command(self.local, console, "new_pool", self.new_pool) + add_command(self.local, console, "activate_pool", self.activate_pool) + add_command(self.local, console, "update_validator_set", self.update_validator_set) + add_command(self.local, console, "withdraw_from_pool", self.withdraw_from_pool) + add_command(self.local, console, "deposit_to_pool", self.deposit_to_pool) diff --git a/modules/pool.py b/modules/pool.py index 16b481c5..8f427a03 100644 --- a/modules/pool.py +++ b/modules/pool.py @@ -2,6 +2,7 @@ from mypylib.mypylib import color_print, print_table from modules.module import MtcModule +from mytonctrl.console_cmd import add_command, check_usage_one_arg, check_usage_two_args class PoolModule(MtcModule): @@ -25,15 +26,12 @@ def print_pools_list(self, args): print_table(table) def delete_pool(self, args): - try: - pool_name = args[0] - except: - color_print("{red}Bad args. Usage:{endc} delete_pool ") + if not check_usage_one_arg("delete_pool", args): return + pool_name = args[0] pool = self.ton.GetLocalPool(pool_name) pool.Delete() color_print("DeletePool - {green}OK{endc}") - # end define def do_import_pool(self, pool_name, addr_b64): self.check_download_pool_contract_scripts() @@ -44,12 +42,10 @@ def do_import_pool(self, pool_name, addr_b64): # end define def import_pool(self, args): - try: - pool_name = args[0] - pool_addr = args[1] - except: - color_print("{red}Bad args. Usage:{endc} import_pool ") + if not check_usage_two_args("import_pool", args): return + pool_name = args[0] + pool_addr = args[1] self.do_import_pool(pool_name, pool_addr) color_print("import_pool - {green}OK{endc}") @@ -59,6 +55,6 @@ def check_download_pool_contract_scripts(self): self.ton.DownloadContract("https://github.com/ton-blockchain/nominator-pool") def add_console_commands(self, console): - console.AddItem("pools_list", self.print_pools_list, self.local.translate("pools_list_cmd")) - console.AddItem("delete_pool", self.delete_pool, self.local.translate("delete_pool_cmd")) - console.AddItem("import_pool", self.import_pool, self.local.translate("import_pool_cmd")) + add_command(self.local, console, "pools_list", self.print_pools_list) + add_command(self.local, console, "delete_pool", self.delete_pool) + add_command(self.local, console, "import_pool", self.import_pool) diff --git a/modules/single_pool.py b/modules/single_pool.py index 45c76f8a..f0a791df 100644 --- a/modules/single_pool.py +++ b/modules/single_pool.py @@ -3,6 +3,7 @@ from mypylib.mypylib import color_print from modules.pool import PoolModule from mytoncore.utils import get_package_resource_path +from mytonctrl.console_cmd import add_command, check_usage_two_args, check_usage_one_arg class SingleNominatorModule(PoolModule): @@ -36,12 +37,10 @@ def do_create_single_pool(self, pool_name, owner_address): raise Exception("create_single_pool error: Pool with the same parameters already exists.") def new_single_pool(self, args): - try: - pool_name = args[0] - owner_address = args[1] - except: - color_print("{red}Bad args. Usage:{endc} new_single_pool ") + if not check_usage_two_args("new_single_pool", args): return + pool_name = args[0] + owner_address = args[1] self.do_create_single_pool(pool_name, owner_address) color_print("new_single_pool - {green}OK{endc}") @@ -54,11 +53,9 @@ def do_activate_single_pool(self, pool): self.ton.SendFile(result_file_path, validator_wallet) def activate_single_pool(self, args): - try: - pool_name = args[0] - except: - color_print("{red}Bad args. Usage:{endc} activate_single_pool ") + if not check_usage_one_arg("activate_single_pool", args): return + pool_name = args[0] pool = self.ton.GetLocalPool(pool_name) if not os.path.isfile(pool.bocFilePath): self.local.add_log(f"Pool {pool_name} already activated", "warning") @@ -67,17 +64,14 @@ def activate_single_pool(self, args): color_print("activate_single_pool - {green}OK{endc}") def withdraw_from_single_pool(self, args): - try: - pool_addr = args[0] - amount = float(args[1]) - except: - color_print("{red}Bad args. Usage:{endc} withdraw_from_single_pool ") + if not check_usage_two_args("withdraw_from_single_pool", args): return + pool_addr = args[0] + amount = float(args[1]) self.ton.WithdrawFromPoolProcess(pool_addr, amount) color_print("withdraw_from_single_pool - {green}OK{endc}") - #end define def add_console_commands(self, console): - console.AddItem("new_single_pool", self.new_single_pool, self.local.translate("new_single_pool_cmd")) - console.AddItem("activate_single_pool", self.activate_single_pool, self.local.translate("activate_single_pool_cmd")) - console.AddItem("withdraw_from_single_pool", self.withdraw_from_single_pool, self.local.translate("withdraw_from_single_pool_cmd")) + add_command(self.local, console, "new_single_pool", self.new_single_pool) + add_command(self.local, console, "activate_single_pool", self.activate_single_pool) + add_command(self.local, console, "withdraw_from_single_pool", self.withdraw_from_single_pool) diff --git a/modules/utilities.py b/modules/utilities.py index 4a015c02..3be2f5c2 100644 --- a/modules/utilities.py +++ b/modules/utilities.py @@ -7,6 +7,7 @@ from mypylib.mypylib import color_print, print_table, color_text, timeago, bcolors from modules.module import MtcModule +from mytonctrl.console_cmd import add_command, check_usage_one_arg, check_usage_two_args class UtilitiesModule(MtcModule): @@ -15,11 +16,9 @@ class UtilitiesModule(MtcModule): default_value = False def view_account_status(self, args): - try: - addrB64 = args[0] - except: - color_print("{red}Bad args. Usage:{endc} vas ") + if not check_usage_one_arg("vas", args): return + addrB64 = args[0] addrB64 = self.ton.get_destination_addr(addrB64) account = self.ton.GetAccount(addrB64) version = self.ton.GetVersionFromCodeHash(account.codeHash) @@ -60,30 +59,22 @@ def get_history_table(self, addr, limit): datetime = timeago(message.time) table += [[datetime, type, message.value, fromto]] return table - # end define def view_account_history(self, args): - try: - addr = args[0] - limit = int(args[1]) - except: - color_print("{red}Bad args. Usage:{endc} vah ") + if not check_usage_two_args("vah", args): return + addr = args[0] + limit = int(args[1]) table = self.get_history_table(addr, limit) print_table(table) - # end define def create_new_bookmark(self, args): - try: - name = args[0] - addr = args[1] - except: - color_print("{red}Bad args. Usage:{endc} nb ") + if not check_usage_two_args("nb", args): return + name = args[0] + addr = args[1] if not self.ton.IsAddr(addr): raise Exception("Incorrect address") - # end if - bookmark = dict() bookmark["name"] = name bookmark["addr"] = addr @@ -107,11 +98,9 @@ def print_bookmarks_list(self, args): # end define def delete_bookmark(self, args): - try: - name = args[0] - except: - color_print("{red}Bad args. Usage:{endc} db ") + if not check_usage_one_arg("db", args): return + name = args[0] self.ton.DeleteBookmark(name) color_print("DeleteBookmark - {green}OK{endc}") # end define @@ -235,14 +224,10 @@ def get_offer_diff(self, offer_hash): # end define def offer_diff(self, args): - try: - offer_hash = args[0] - offer_hash = offer_hash - except: - color_print("{red}Bad args. Usage:{endc} od ") + if not check_usage_one_arg("od", args): return + offer_hash = args[0] self.get_offer_diff(offer_hash) - # end define def print_complaints_list(self, args): past = "past" in args @@ -370,11 +355,9 @@ def check_adnl_connection(self): return ok, error def get_pool_data(self, args): - try: - pool_name = args[0] - except: - color_print("{red}Bad args. Usage:{endc} get_pool_data ") + if not check_usage_one_arg("get_pool_data", args): return + pool_name = args[0] if self.ton.IsAddr(pool_name): pool_addr = pool_name else: @@ -385,18 +368,14 @@ def get_pool_data(self, args): # end define def add_console_commands(self, console): - console.AddItem("vas", self.view_account_status, self.local.translate("vas_cmd")) - console.AddItem("vah", self.view_account_history, self.local.translate("vah_cmd")) - - console.AddItem("nb", self.create_new_bookmark, self.local.translate("nb_cmd")) - console.AddItem("bl", self.print_bookmarks_list, self.local.translate("bl_cmd")) - console.AddItem("db", self.delete_bookmark, self.local.translate("db_cmd")) - - console.AddItem("ol", self.print_offers_list, self.local.translate("ol_cmd")) - console.AddItem("od", self.offer_diff, self.local.translate("od_cmd")) - - console.AddItem("el", self.print_election_entries_list, self.local.translate("el_cmd")) - console.AddItem("vl", self.print_validator_list, self.local.translate("vl_cmd")) - console.AddItem("cl", self.print_complaints_list, self.local.translate("cl_cmd")) - - console.AddItem("get_pool_data", self.get_pool_data, self.local.translate("get_pool_data_cmd")) + add_command(self.local, console, "vas", self.view_account_status) + add_command(self.local, console, "vah", self.view_account_history) + add_command(self.local, console, "nb", self.create_new_bookmark) + add_command(self.local, console, "bl", self.print_bookmarks_list) + add_command(self.local, console, "db", self.delete_bookmark) + add_command(self.local, console, "ol", self.print_offers_list) + add_command(self.local, console, "od", self.offer_diff) + add_command(self.local, console, "el", self.print_election_entries_list) + add_command(self.local, console, "vl", self.print_validator_list) + add_command(self.local, console, "cl", self.print_complaints_list) + add_command(self.local, console, "get_pool_data", self.get_pool_data) diff --git a/modules/validator.py b/modules/validator.py index 3d0fbeff..4d7df9e6 100644 --- a/modules/validator.py +++ b/modules/validator.py @@ -5,6 +5,8 @@ from mypylib.mypylib import color_print, get_timestamp from modules.module import MtcModule from mytoncore import hex_shard_to_int, hex2b64 +from mytonctrl.console_cmd import check_usage_two_args, add_command, check_usage_args_min_max_len + from mytonctrl.utils import timestamp2utcdatetime, GetColorInt, pop_arg_from_args, is_hex @@ -16,8 +18,7 @@ class ValidatorModule(MtcModule): default_value = True def vote_offer(self, args): - if len(args) == 0: - color_print("{red}Bad args. Usage:{endc} vo ") + if not check_usage_args_min_max_len("vo", args, min_len=1, max_len=1000): return offers = self.ton.GetOffers() for offer_hash in args: @@ -34,12 +35,10 @@ def vote_election_entry(self, args): color_print("VoteElectionEntry - {green}OK{endc}") def vote_complaint(self, args): - try: - election_id = args[0] - complaint_hash = args[1] - except: - color_print("{red}Bad args. Usage:{endc} vc ") + if not check_usage_two_args("vc", args): return + election_id = args[0] + complaint_hash = args[1] self.ton.VoteComplaint(election_id, complaint_hash) color_print("VoteComplaint - {green}OK{endc}") @@ -159,8 +158,7 @@ def set_collators_list(self, collators_list: dict): raise Exception(f'Failed to set collators list: {result}') def add_collator(self, args: list): - if len(args) < 2: - color_print("{red}Bad args. Usage:{endc} add_collator [--self-collate ] [--select-mode ]") + if not check_usage_args_min_max_len("add_collator", args, min_len=2, max_len=6): return adnl = args[0] shard = args[1] @@ -202,8 +200,7 @@ def add_collator(self, args: list): color_print("add_collator - {green}OK{endc}") def delete_collator(self, args: list): - if len(args) < 1: - color_print("{red}Bad args. Usage:{endc} delete_collator [shard] ") + if not check_usage_args_min_max_len("delete_collator", args, min_len=1, max_len=2): return shard_id = None @@ -274,11 +271,11 @@ def reset_collators(self, args: list): color_print("reset_collators - {green}OK{endc}") def add_console_commands(self, console): - console.AddItem("vo", self.vote_offer, self.local.translate("vo_cmd")) - console.AddItem("ve", self.vote_election_entry, self.local.translate("ve_cmd")) - console.AddItem("vc", self.vote_complaint, self.local.translate("vc_cmd")) - console.AddItem("check_ef", self.check_efficiency, self.local.translate("check_ef_cmd")) - console.AddItem("add_collator", self.add_collator, self.local.translate("add_collator_cmd")) - console.AddItem("delete_collator", self.delete_collator, self.local.translate("delete_collator_cmd")) - console.AddItem("print_collators", self.print_collators, self.local.translate("print_collators_cmd")) - console.AddItem("reset_collators", self.reset_collators, self.local.translate("reset_collators_cmd")) + add_command(self.local, console, "vo", self.vote_offer) + add_command(self.local, console, "ve", self.vote_election_entry) + add_command(self.local, console, "vc", self.vote_complaint) + add_command(self.local, console, "check_ef", self.check_efficiency) + add_command(self.local, console, "add_collator", self.add_collator) + add_command(self.local, console, "delete_collator", self.delete_collator) + add_command(self.local, console, "print_collators", self.print_collators) + add_command(self.local, console, "reset_collators", self.reset_collators) diff --git a/modules/wallet.py b/modules/wallet.py index e4bc1c86..4cb193ed 100644 --- a/modules/wallet.py +++ b/modules/wallet.py @@ -3,6 +3,9 @@ from modules.module import MtcModule from mypylib.mypylib import color_print, print_table +from mytonctrl.console_cmd import (check_usage_no_args, check_usage_one_arg, check_usage_two_args, + add_command, check_usage_args_len, check_usage_args_min_len, check_usage_args_min_max_len, check_usage_args_lens +) class WalletModule(MtcModule): @@ -11,29 +14,26 @@ class WalletModule(MtcModule): default_value = False def create_new_wallet(self, args): - version = "v1" - try: - if len(args) == 0: - walletName = self.ton.GenerateWalletName() - workchain = 0 - else: - workchain = int(args[0]) - walletName = args[1] - if len(args) > 2: - version = args[2] - if len(args) == 4: - subwallet = int(args[3]) - else: - subwallet = 698983191 + workchain # 0x29A9A317 + workchain - except: - color_print("{red}Bad args. Usage:{endc} nw [ ]") + if not check_usage_args_lens("nw", args, [0, 2, 3, 4]): return + version = "v1" + if len(args) == 0: + walletName = self.ton.GenerateWalletName() + workchain = 0 + else: + workchain = int(args[0]) + walletName = args[1] + if len(args) > 2: + version = args[2] + if len(args) == 4: + subwallet = int(args[3]) + else: + subwallet = 698983191 + workchain # 0x29A9A317 + workchain wallet = self.ton.CreateWallet(walletName, workchain, version, subwallet=subwallet) table = list() table += [["Name", "Workchain", "Address"]] table += [[wallet.name, wallet.workchain, wallet.addrB64_init]] print_table(table) - # end define def _wallets_check(self): self.local.add_log("start WalletsCheck function", "debug") @@ -43,20 +43,17 @@ def _wallets_check(self): account = self.ton.GetAccount(wallet.addrB64) if account.balance > 0: self.ton.SendFile(wallet.bocFilePath, wallet) - # end define def activate_wallet(self, args): - try: - walletName = args[0] - except Exception as err: - walletName = "all" - if walletName == "all": + if not check_usage_one_arg("aw", args): + return + wallet_name = args[0] + if wallet_name == "--all": self._wallets_check() else: - wallet = self.ton.GetLocalWallet(walletName) + wallet = self.ton.GetLocalWallet(wallet_name) self.ton.ActivateWallet(wallet) color_print("ActivateWallet - {green}OK{endc}") - # end define def get_wallets(self): self.local.add_log("start GetWallets function", "debug") @@ -66,9 +63,10 @@ def get_wallets(self): wallet = self.ton.GetLocalWallet(walletName) wallets.append(wallet) return wallets - # end define def print_wallets_list(self, args): + if not check_usage_no_args("wl", args): + return table = list() table += [["Name", "Status", "Balance", "Ver", "Wch", "Address"]] data = self.get_wallets() @@ -81,7 +79,6 @@ def print_wallets_list(self, args): wallet.addrB64 = wallet.addrB64_init table += [[wallet.name, account.status, account.balance, wallet.version, wallet.workchain, wallet.addrB64]] print_table(table) - # end define def do_import_wallet(self, addr_b64, key): addr_bytes = self.ton.addr_b64_to_bytes(addr_b64) @@ -93,29 +90,20 @@ def do_import_wallet(self, addr_b64, key): with open(wallet_path + ".pk", 'wb') as file: file.write(pk_bytes) return wallet_name - # end define def import_wallet(self, args): - try: - addr = args[0] - key = args[1] - except: - color_print("{red}Bad args. Usage:{endc} iw ") + if not check_usage_two_args("iw", args): return + addr, key = args[0], args[1] name = self.do_import_wallet(addr, key) print("Wallet name:", name) - # end define def set_wallet_version(self, args): - try: - addr = args[0] - version = args[1] - except: - color_print("{red}Bad args. Usage:{endc} swv ") + if not check_usage_two_args("swv", args): return + addr, version = args[0], args[1] self.ton.SetWalletVersion(addr, version) color_print("SetWalletVersion - {green}OK{endc}") - # end define def do_export_wallet(self, wallet_name): wallet = self.ton.GetLocalWallet(wallet_name) @@ -123,48 +111,36 @@ def do_export_wallet(self, wallet_name): data = file.read() key = base64.b64encode(data).decode("utf-8") return wallet.addrB64, key - # end define def export_wallet(self, args): - try: - name = args[0] - except: - color_print("{red}Bad args. Usage:{endc} ew ") + if not check_usage_one_arg("ew", args): return + name = args[0] addr, key = self.do_export_wallet(name) print("Wallet name:", name) print("Address:", addr) print("Secret key:", key) - # end define def delete_wallet(self, args): - try: - wallet_name = args[0] - except: - color_print("{red}Bad args. Usage:{endc} dw ") + if not check_usage_one_arg("dw", args): return + wallet_name = args[0] if input("Are you sure you want to delete this wallet (yes/no): ") != "yes": print("Cancel wallet deletion") return wallet = self.ton.GetLocalWallet(wallet_name) wallet.Delete() color_print("DeleteWallet - {green}OK{endc}") - # end define def move_coins(self, args): - try: - wallet_name = args[0] - destination = args[1] - amount = args[2] - flags = args[3:] - except: - color_print("{red}Bad args. Usage:{endc} mg ") + if not check_usage_args_min_len("mg", args, 3): return + wallet_name, destination, amount = args[0], args[1], args[2] + flags = args[3:] wallet = self.ton.GetLocalWallet(wallet_name) destination = self.ton.get_destination_addr(destination) self.ton.MoveCoins(wallet, destination, amount, flags=flags) color_print("MoveCoins - {green}OK{endc}") - # end define def do_move_coins_through_proxy(self, wallet, dest, coins): self.local.add_log("start MoveCoinsThroughProxy function", "debug") @@ -177,29 +153,23 @@ def do_move_coins_through_proxy(self, wallet, dest, coins): self.ton.MoveCoins(wallet2, dest, "alld", flags=["-n"]) wallet1.Delete() wallet2.Delete() - # end define def move_coins_through_proxy(self, args): - try: - wallet_name = args[0] - destination = args[1] - amount = args[2] - except: - color_print("{red}Bad args. Usage:{endc} mgtp ") + if not check_usage_args_len("mgtp", args, 3): return + wallet_name, destination, amount = args[0], args[1], args[2] wallet = self.ton.GetLocalWallet(wallet_name) destination = self.ton.get_destination_addr(destination) self.do_move_coins_through_proxy(wallet, destination, amount) color_print("MoveCoinsThroughProxy - {green}OK{endc}") - # end define def add_console_commands(self, console): - console.AddItem("nw", self.create_new_wallet, self.local.translate("nw_cmd")) - console.AddItem("aw", self.activate_wallet, self.local.translate("aw_cmd")) - console.AddItem("wl", self.print_wallets_list, self.local.translate("wl_cmd")) - console.AddItem("iw", self.import_wallet, self.local.translate("iw_cmd")) - console.AddItem("swv", self.set_wallet_version, self.local.translate("swv_cmd")) - console.AddItem("ew", self.export_wallet, self.local.translate("ex_cmd")) - console.AddItem("dw", self.delete_wallet, self.local.translate("dw_cmd")) - console.AddItem("mg", self.move_coins, self.local.translate("mg_cmd")) - console.AddItem("mgtp", self.move_coins_through_proxy, self.local.translate("mgtp_cmd")) + add_command(self.local, console, "nw", self.create_new_wallet) + add_command(self.local, console, "aw", self.activate_wallet) + add_command(self.local, console, "wl", self.print_wallets_list) + add_command(self.local, console, "iw", self.import_wallet) + add_command(self.local, console, "swv", self.set_wallet_version) + add_command(self.local, console, "ew", self.export_wallet) + add_command(self.local, console, "dw", self.delete_wallet) + add_command(self.local, console, "mg", self.move_coins) + add_command(self.local, console, "mgtp", self.move_coins_through_proxy) diff --git a/mypyconsole b/mypyconsole index 9b730946..cc4bb777 160000 --- a/mypyconsole +++ b/mypyconsole @@ -1 +1 @@ -Subproject commit 9b730946fc7998a6b294fe9adb7a77ce1b2b6eef +Subproject commit cc4bb7779a204a9a8e26ccb401f014702d683da5 diff --git a/mytonctrl/console_cmd.py b/mytonctrl/console_cmd.py new file mode 100644 index 00000000..b2d6235c --- /dev/null +++ b/mytonctrl/console_cmd.py @@ -0,0 +1,121 @@ +import typing + +from mypyconsole.mypyconsole import MyPyConsole +from mypylib import MyPyClass, color_print + +USAGES = { + "update": "[repo_url|repo_owner] [branch]", + "upgrade": "[repo_url|repo_owner] [branch]", + "installer": "[command]", + "status": "[fast]", + "enable_mode": "", + "disable_mode": "", + "about": "", + "get": "", + "set": " [--force]", + "create_backup": "[filename] [-u ]", + "restore_backup": " [-y] [--skip-create-backup] [-u ]", + "add_custom_overlay": " ", + "delete_custom_overlay": "", + "remove_btc_teleport": "[--force]", + "vo": "[ ...]", + "vc": " ", + "add_collator": " [--self-collate ] [--select-mode ]", + "delete_collator": "[shard] ", + "print_collators": "[--json]", + "nw": "[ [] []]", + "aw": "|--all", + "iw": " ", + "swv": " ", + "ew": "", + "dw": "", + "wl": "", + "mg": " [flags...]", + "mgtp": " ", + "vas": "", + "vah": " ", + "nb": " ", + "bl": "", + "db": "", + "ol": "[--json] [hash]", + "od": "", + "el": "[past] [--json] [adnl] [pubkey] [wallet]", + "vl": "[past] [fast] [offline] [--json] [adnl] [pubkey] [wallet]", + "cl": "[past] [--json] [adnl]", + "get_pool_data": "", + "delete_pool": "", + "import_pool": " ", + "new_pool": " ", + "activate_pool": "", + "update_validator_set": "", + "withdraw_from_pool": " ", + "deposit_to_pool": " ", + "new_single_pool": " ", + "activate_single_pool": "", + "withdraw_from_single_pool": " ", + "get_controller_data": "", + "deposit_to_controller": " ", + "withdraw_from_controller": " [amount]", + "calculate_annual_controller_percentage": "[percent_per_round]", + "controller_update_validator_set": "", + "stop_controller": "", + "stop_and_withdraw_controller": " [amount]", + "add_controller": "", + "set_collation_config": "", + "setup_collator": "[--force] [--adnl ] [shard2] ...", + "add_validator_to_collation_wl": " [adnl2] [adnl3] ...", + "delete_validator_from_collation_wl": " [adnl2] [adnl3] ...", + "stop_collator": "[ ]", + "enable_alert": "", + "disable_alert": "", + "setup_alert_bot": " ", +} + + +def check_usage_no_args(name: str, args: list) -> bool: + return check_usage(name, args, lambda x: len(x) == 0) + + +def check_usage_one_arg(name: str, args: list) -> bool: + return check_usage(name, args, lambda x: len(x) == 1) + + +def check_usage_two_args(name: str, args: list) -> bool: + return check_usage(name, args, lambda x: len(x) == 2) + + +def check_usage_args_len(name: str, args: list, len_: int) -> bool: + return check_usage(name, args, lambda x: len(x) == len_) + + +def check_usage_args_lens(name: str, args: list, lens: list) -> bool: + return check_usage(name, args, lambda x: len(x) in lens) + + +def check_usage_args_min_len(name: str, args: list, min_len: int) -> bool: + return check_usage(name, args, lambda x: len(x) >= min_len) + + +def check_usage_args_min_max_len(name: str, args: list, min_len: int, max_len: int) -> bool: + return check_usage(name, args, lambda x: min_len <= len(x) <= max_len) + + +def check_usage(name: str, args: list, check_fun: typing.Callable) -> bool: + usage = get_usage(name) + if check_fun(args): + return True + else: + color_print(f"{{red}}Bad args. Usage:{{endc}} {name} {usage}") + return False + + +def get_usage(name: str) -> str: + return USAGES.get(name, '') + + +def add_command(local: MyPyClass, console: MyPyConsole, name: str, function: typing.Callable): + desc = local.translate(f"{name}_cmd") + usage = get_usage(name) + # if usage: + # desc += f"\nUsage: {usage}" + console.add_item(name, function, desc, usage) diff --git a/mytonctrl/mytonctrl.py b/mytonctrl/mytonctrl.py index 901dfd12..1462852b 100755 --- a/mytonctrl/mytonctrl.py +++ b/mytonctrl/mytonctrl.py @@ -42,6 +42,7 @@ ) from mytoncore.utils import get_package_resource_path from mytoncore.telemetry import is_host_virtual +from mytonctrl.console_cmd import add_command, check_usage_one_arg, check_usage_args_min_max_len from mytonctrl.migrate import run_migrations from mytonctrl.utils import GetItemFromList, timestamp2utcdatetime, fix_git_config, is_hex, GetColorInt, \ pop_user_from_args, pop_arg_from_args @@ -70,19 +71,19 @@ def inject_globals(func): console.debug = ton.GetSettings("debug") console.local = local - console.AddItem("update", inject_globals(Update), local.translate("update_cmd")) - console.AddItem("upgrade", inject_globals(Upgrade), local.translate("upgrade_cmd")) - console.AddItem("installer", inject_globals(Installer), local.translate("installer_cmd")) - console.AddItem("status", inject_globals(PrintStatus), local.translate("status_cmd")) - console.AddItem("status_modes", inject_globals(mode_status), local.translate("status_modes_cmd")) - console.AddItem("status_settings", inject_globals(settings_status), local.translate("settings_status_cmd")) - console.AddItem("enable_mode", inject_globals(enable_mode), local.translate("enable_mode_cmd")) - console.AddItem("disable_mode", inject_globals(disable_mode), local.translate("disable_mode_cmd")) - console.AddItem("about", inject_globals(about), local.translate("about_cmd")) - console.AddItem("get", inject_globals(GetSettings), local.translate("get_cmd")) - console.AddItem("set", inject_globals(SetSettings), local.translate("set_cmd")) - console.AddItem("rollback", inject_globals(rollback_to_mtc1), local.translate("rollback_cmd")) - console.AddItem("download_archive_blocks", inject_globals(download_archive_blocks), local.translate("download_archive_blocks_cmd")) + add_command(local, console, "update", inject_globals(Update)) + add_command(local, console, "upgrade", inject_globals(Upgrade)) + add_command(local, console, "installer", inject_globals(Installer)) + add_command(local, console, "status", inject_globals(PrintStatus)) + add_command(local, console, "status_modes", inject_globals(mode_status)) + add_command(local, console, "status_settings", inject_globals(settings_status)) + add_command(local, console, "enable_mode", inject_globals(enable_mode)) + add_command(local, console, "disable_mode", inject_globals(disable_mode)) + add_command(local, console, "about", inject_globals(about)) + add_command(local, console, "get", inject_globals(GetSettings)) + add_command(local, console, "set", inject_globals(SetSettings)) + add_command(local, console, "rollback", inject_globals(rollback_to_mtc1)) + add_command(local, console, "download_archive_blocks", inject_globals(download_archive_blocks)) from modules.backups import BackupModule module = BackupModule(ton, local) @@ -144,7 +145,7 @@ def inject_globals(func): module = AlertBotModule(ton, local) module.add_console_commands(console) - console.AddItem("benchmark", inject_globals(run_benchmark), local.translate("benchmark_cmd")) + add_command(local, console, "benchmark", inject_globals(run_benchmark)) # Process input parameters opts, args = getopt.getopt(argv,"hc:w:",["config=","wallets="]) @@ -177,8 +178,7 @@ def inject_globals(func): def about(local, ton, args): from modules import get_mode, get_mode_settings - if len(args) != 1: - color_print("{red}Bad args. Usage:{endc} about ") + if not check_usage_one_arg("about", args): return mode_name = args[0] mode = get_mode(mode_name) @@ -192,7 +192,6 @@ def about(local, ton, args): print('Settings:', 'no' if len(mode_settings) == 0 else '') for setting_name, setting in mode_settings.items(): color_print(f' {{bold}}{setting_name}{{endc}}: {setting.description}.\n Default value: {setting.default_value}') -#end define def check_installer_user(local): @@ -1012,22 +1011,18 @@ def GetColorTime(datetime, timestamp): #end define def GetSettings(ton, args): - try: - name = args[0] - except IndexError: - color_print("{red}Bad args. Usage:{endc} get ") + if not check_usage_one_arg("get", args): return + name = args[0] result = ton.GetSettings(name) print(json.dumps(result, indent=2)) #end define def SetSettings(local, ton, args): - try: - name = args[0] - value = args[1] - except IndexError: - color_print("{red}Bad args. Usage:{endc} set ") + if not check_usage_args_min_max_len("set", args, min_len=2, max_len=3): return + name = args[0] + value = args[1] if name == 'usePool' or name == 'useController': mode_name = 'nominator-pool' if name == 'usePool' else 'liquid-staking' color_print(f"{{red}} Error: set {name} ... is deprecated and does not work {{endc}}." @@ -1052,26 +1047,21 @@ def SetSettings(local, ton, args): def enable_mode(local, ton, args): - try: - name = args[0] - except IndexError: - color_print("{red}Bad args. Usage:{endc} enable_mode ") + if not check_usage_one_arg("enable_mode", args): return + name = args[0] ton.enable_mode(name) color_print("enable_mode - {green}OK{endc}") local.exit() -#end define + def disable_mode(local, ton, args): - try: - name = args[0] - except IndexError: - color_print("{red}Bad args. Usage:{endc} disable_mode ") + if not check_usage_one_arg("disable_mode", args): return + name = args[0] ton.disable_mode(name) color_print("disable_mode - {green}OK{endc}") local.exit() -#end define def download_archive_blocks(local, args: list): diff --git a/mytonctrl/resources/translate.json b/mytonctrl/resources/translate.json index a3780797..dc64564c 100644 --- a/mytonctrl/resources/translate.json +++ b/mytonctrl/resources/translate.json @@ -19,7 +19,7 @@ "ru": "Показать режимы MTC", "zh_TW": "顯示 MTC 模式" }, - "settings_status_cmd": { + "status_settings_cmd": { "en": "Show all available settings with their description and values", "ru": "Показать все доступные настройки с их описанием и значениями", "zh_TW": "顯示所有可用設定及其描述和值" @@ -44,6 +44,16 @@ "ru": "Откатиться к mytonctrl 1.0", "zh_TW": "回滾到 mytonctrl 1.0" }, + "create_backup_cmd": { + "en": "Create backup of MyTonCtrl", + "ru": "Создать резервную копию MyTonCtrl", + "zh_TW": "創建 MyTonCtrl 備份" + }, + "restore_backup_cmd": { + "en": "Restore MyTonCtrl from backup", + "ru": "Восстановить MyTonCtrl из резервной копии", + "zh_TW": "從備份還原 MyTonCtrl" + }, "seqno_cmd": { "en": "Get seqno wallet", "ru": "Получить seqno кошелька", @@ -79,7 +89,7 @@ "ru": "Установить версию кошелька", "zh_TW": "設定錢包版本" }, - "ex_cmd": { + "ew_cmd": { "en": "Export wallet", "ru": "Экспортировать кошелек", "zh_TW": "匯出錢包" @@ -159,6 +169,131 @@ "ru": "Показать действующие жалобы", "zh_TW": "顯示投訴列表" }, + "get_pool_data_cmd": { + "en": "Print `get_pool_data` Get Method result for pool", + "ru": "Показать результат Get Method `get_pool_data` для пула", + "zh_TW": "列印池的 `get_pool_data` 獲取方法結果" + }, + "pools_list_cmd": { + "en": "Show pools list", + "ru": "Показать список пулов", + "zh_TW": "顯示池列表" + }, + "delete_pool_cmd": { + "en": "Delete pool from pools list", + "ru": "Удалить пул из списка пулов", + "zh_TW": "從池列表中刪除池" + }, + "import_pool_cmd": { + "en": "Import pool to pools list", + "ru": "Импортировать пул в список пулов", + "zh_TW": "將池匯入池列表" + }, + "new_pool_cmd": { + "en": "Create new nominator pool", + "ru": "Создать новый пул номинаторов", + "zh_TW": "創建新的提名池" + }, + "activate_pool_cmd": { + "en": "Activate pool", + "ru": "Активировать пул", + "zh_TW": "啟用池" + }, + "update_validator_set_cmd": { + "en": "Update validator set on pool and recover stake if possible", + "ru": "Обновить набор валидаторов в пуле и восстановить стейк, если возможно", + "zh_TW": "更新池中的驗證者集並在可能的情況下恢復賭注" + }, + "withdraw_from_pool_cmd": { + "en": "Withdraw validator stake from pool", + "ru": "Вывести стейк валидатора из пула", + "zh_TW": "從池中提取驗證者賭注" + }, + "deposit_to_pool_cmd": { + "en": "Deposit validator stake to pool", + "ru": "Внести стейк валидатора в пул", + "zh_TW": "將驗證者賭注存入池中" + }, + "new_single_pool_cmd": { + "en": "Create new single-nominator pool", + "ru": "Создать новый пул single-nominator", + "zh_TW": "創建新的單提名池" + }, + "activate_single_pool_cmd": { + "en": "Activate single-nominator pool", + "ru": "Активировать пул single-nominator", + "zh_TW": "啟用單提名池" + }, + "withdraw_from_single_pool_cmd": { + "en": "Withdraw from single-nominator pool", + "ru": "Вывести из пула single-nominator", + "zh_TW": "從單提名池中提取" + }, + "create_controllers_cmd": { + "en": "Create liquid staking controllers", + "ru": "Создать контроллеры для liquid staking", + "zh_TW": "創建流動質押控制器" + }, + "update_controllers_cmd": { + "en": "Update liquid staking controllers", + "ru": "Обновить контроллеры для liquid staking", + "zh_TW": "更新流動質押控制器" + }, + "controllers_list_cmd": { + "en": "Show liquid staking controllers list", + "ru": "Показать список контроллеров для liquid staking", + "zh_TW": "顯示流動質押控制器列表" + }, + "get_controller_data_cmd": { + "en": "Print `all_data` Get Method result for controller", + "ru": "Показать результат Get Method `all_data` для контроллера", + "zh_TW": "列印控制器的 `all_data` 獲取方法結果" + }, + "deposit_to_controller_cmd": { + "en": "Deposit to liquid staking controller from validator's wallet", + "ru": "Внести на контроллер для liquid staking из кошелька валидатора", + "zh_TW": "從驗證者錢包存入流動質押控制器" + }, + "withdraw_from_controller_cmd": { + "en": "Withdraw coins from liquid staking controller", + "ru": "Вывести монеты с контроллера для liquid staking", + "zh_TW": "從流動質押控制器提取幣" + }, + "calculate_annual_controller_percentage_cmd": { + "en": "Calculate annual percentage for liquid staking controller", + "ru": "Рассчитать годовой процент для контроллера liquid staking", + "zh_TW": "計算流動質押控制器的年利率" + }, + "controller_update_validator_set_cmd": { + "en": "Manually start liquid staking controller processing", + "ru": "Вручную запустить обработку контроллера liquid staking", + "zh_TW": "手動啟動流動質押控制器處理" + }, + "stop_controller_cmd": { + "en": "Stop liquid staking controller", + "ru": "Остановить контроллер liquid staking", + "zh_TW": "停止流動質押控制器" + }, + "stop_and_withdraw_controller_cmd": { + "en": "Stop and withdraw from liquid staking controller", + "ru": "Остановить и вывести с контроллера liquid staking", + "zh_TW": "停止並從流動質押控制器提取" + }, + "add_controller_cmd": { + "en": "Add liquid staking controller to validator", + "ru": "Добавить контроллер liquid staking к валидатору", + "zh_TW": "將流動質押控制器添加到驗證者" + }, + "check_liquid_pool_cmd": { + "en": "Check liquid staking pool", + "ru": "Проверить пул liquid staking", + "zh_TW": "檢查流動質押池" + }, + "test_calculate_loan_amount_cmd": { + "en": "Test calculate loan amount for liquid staking controller", + "ru": "Тест рассчета суммы займа для контроллера liquid staking", + "zh_TW": "測試計算流動質押控制器的貸款金額" + }, "vc_cmd": { "en": "Vote for complaint", "ru": "Голосовать за жалобу", @@ -175,18 +310,18 @@ "zh_TW": "投票選舉入口" }, "vl_cmd": { - "en": "Show active validators", + "en": "Show current validators", "ru": "Показать действующие валидаторы", "zh_TW": "顯示活躍的驗證者" }, "get_cmd": { - "en": "Get settings", - "ru": "Посмотреть настройки", + "en": "Get setting", + "ru": "Посмотреть настройку", "zh_TW": "獲取設定" }, "set_cmd": { - "en": "Set settings", - "ru": "Задать настройки", + "en": "Set setting", + "ru": "Задать настройку", "zh_TW": "設定設定" }, "hr_cmd": { @@ -205,15 +340,35 @@ "zh_TW": "禁用挖礦" }, "installer_cmd": { - "en": "Run the installer of TON modules", - "ru": "Запустить установщик модулей TON", - "zh_TW": "執行 TON 模組的安裝程序" + "en": "Run the installer of TON modules CLI or specific command", + "ru": "Запустить установщик модулей TON CLI или конкретную команду", + "zh_TW": "運行 TON 模塊 CLI 或特定命令的安裝程式" }, "check_ef_cmd": { "en": "Check the efficiency of the validator", "ru": "Проверить эффективность валидатора", "zh_TW": "檢查驗證者的效率" }, + "add_collator_cmd": { + "en": "Add collator to validator", + "ru": "Добавить коллатор к валидатору", + "zh_TW": "將協作者添加到驗證者" + }, + "delete_collator_cmd": { + "en": "Delete collator from this validator collators list", + "ru": "Удалить коллатор из списка коллаторов этого валидатора", + "zh_TW": "從此驗證者協作者列表中刪除協作者" + }, + "print_collators_cmd": { + "en": "Print collators of this validator", + "ru": "Показать коллаторы этого валидатора", + "zh_TW": "列印此驗證者的協作者" + }, + "reset_collators_cmd": { + "en": "Reset collators list", + "ru": "Сбросить список коллаторов", + "zh_TW": "重置協作者列表" + }, "ton_status_head": { "en": "{cyan}===[ TON network status ]==={endc}", "ru": "{cyan}===[ Статус сети TON ]==={endc}", @@ -570,9 +725,9 @@ "zh_TW": "設置協作者" }, "print_local_collators_cmd": { - "en": "Print collators", - "ru": "Показать коллаторы", - "zh_TW": "顯示協作者" + "en": "Print collators running on this node", + "ru": "Показать коллаторы, работающие на этой ноде", + "zh_TW": "列印在此節點上運行的協作者" }, "benchmark_cmd": { "en": "Run benchmark", @@ -599,6 +754,32 @@ "ru": "Скачать архивные блоки из TON Storage", "zh_TW": "從 TON Storage 下載存檔區塊" }, + "add_validator_to_collation_wl_cmd": { + "en": "Add validator to block collation whitelist", + "ru": "Добавить валидатора в вайтлист сборки блоков", + "zh_TW": "將驗證者添加到區塊彙編白名單" + }, + "delete_validator_from_collation_wl_cmd": { + "en": "Remove validator from block collation whitelist", + "ru": "Удалить валидатора из вайтлиста сборки блоков", + "zh_TW": "從區塊彙編白名單中刪除驗證者" + }, + "disable_collation_wl_cmd": { + "en": "Disable block collation whitelist", + "ru": "Отключить вайтлист сборки блоков", + "zh_TW": "禁用區塊彙編白名單" + }, + "print_collation_whitelist_cmd": { + "en": "Print block collation whitelist", + "ru": "Показать вайтлист сборки блоков", + "zh_TW": "列印區塊彙編白名單" + }, + "stop_collator_cmd": { + "en": "Stop running collator on this node. Use without args to stop all collators", + "ru": "Остановить работающий коллатор на этой ноде. Используйте без аргументов, чтобы остановить все коллаторы", + "zh_TW": "停止在此節點上運行的協作者。無參數使用以停止所有協作者" + }, + "000a": { "en": "001", "ru": "002", diff --git a/mytoninstaller/mytoninstaller.py b/mytoninstaller/mytoninstaller.py index fc660793..387f3e10 100644 --- a/mytoninstaller/mytoninstaller.py +++ b/mytoninstaller/mytoninstaller.py @@ -77,17 +77,17 @@ def inject_globals(func): # Create user console console.name = "MyTonInstaller" console.color = console.RED - console.AddItem("status", inject_globals(Status), "Print TON component status") - console.AddItem("set_node_argument", inject_globals(set_node_argument), "Set node argument") - console.AddItem("enable", inject_globals(Enable), "Enable some function") - console.AddItem("update", inject_globals(Enable), "Update some function: 'JR' - jsonrpc. Example: 'update JR'") - console.AddItem("plsc", inject_globals(PrintLiteServerConfig), "Print lite-server config") - console.AddItem("clcf", inject_globals(CreateLocalConfigFile), "Create lite-server config file") - console.AddItem("print_ls_proxy_config", inject_globals(print_ls_proxy_config), "Print ls-proxy config") - console.AddItem("create_ls_proxy_config_file", inject_globals(create_ls_proxy_config_file), "Create ls-proxy config file") - console.AddItem("drvcf", inject_globals(DRVCF), "Dangerous recovery validator config file") - console.AddItem("setwebpass", inject_globals(SetWebPassword), "Set a password for the web admin interface") - console.AddItem("ton_storage_list", inject_globals(ton_storage_list), "Print result of /list method at Ton Storage API") + console.add_item("status", inject_globals(Status), "Print TON component status") + console.add_item("set_node_argument", inject_globals(set_node_argument), "Set node argument", " [arg_value1] [arg_value2] [-d (to delete)]") + console.add_item("enable", inject_globals(Enable), "Enable some function", "") + console.add_item("update", inject_globals(Enable), "Update some function: 'JR' - jsonrpc. Example: 'update JR'", "") + console.add_item("plsc", inject_globals(PrintLiteServerConfig), "Print lite-server config") + console.add_item("clcf", inject_globals(CreateLocalConfigFile), "Create lite-server config file", "[-u ]") + console.add_item("print_ls_proxy_config", inject_globals(print_ls_proxy_config), "Print ls-proxy config") + console.add_item("create_ls_proxy_config_file", inject_globals(create_ls_proxy_config_file), "Create ls-proxy config file") + console.add_item("drvcf", inject_globals(DRVCF), "Dangerous recovery validator config file") + console.add_item("setwebpass", inject_globals(SetWebPassword), "Set a password for the web admin interface") + console.add_item("ton_storage_list", inject_globals(ton_storage_list), "Print result of /list method at Ton Storage API") Refresh(local) #end define diff --git a/tests/integration/test_wallet_commands.py b/tests/integration/test_wallet_commands.py index 39b71510..ffcefe78 100644 --- a/tests/integration/test_wallet_commands.py +++ b/tests/integration/test_wallet_commands.py @@ -73,6 +73,10 @@ def fake_create_wallet(self, wallet_name, workchain, version, subwallet): def test_aw(cli, ton, monkeypatch, mocker: MockerFixture): + # Bad args + output = cli.execute("aw", no_color=True) + assert "Bad args" in output + get_local_wallet_mock = mocker.Mock() activate_wallet_mock = mocker.Mock() wallets_check_mock = mocker.Mock() @@ -92,18 +96,7 @@ def test_aw(cli, ton, monkeypatch, mocker: MockerFixture): get_local_wallet_mock.reset_mock() activate_wallet_mock.reset_mock() wallets_check_mock.reset_mock() - output = cli.execute("aw all", no_color=True) - - get_local_wallet_mock.assert_not_called() - activate_wallet_mock.assert_not_called() - wallets_check_mock.assert_called_once() - assert "ActivateWallet - OK" in output - - # no args, same as all - get_local_wallet_mock.reset_mock() - activate_wallet_mock.reset_mock() - wallets_check_mock.reset_mock() - output = cli.execute("aw", no_color=True) + output = cli.execute("aw --all", no_color=True) get_local_wallet_mock.assert_not_called() activate_wallet_mock.assert_not_called()