diff --git a/modules/__init__.py b/modules/__init__.py index 5a44fa3e..298302b0 100644 --- a/modules/__init__.py +++ b/modules/__init__.py @@ -52,6 +52,7 @@ class Setting: 'fift_timeout': Setting(None, 3, 'Fift default timeout'), 'useDefaultCustomOverlays': Setting(None, True, 'Participate in default custom overlays node eligible to'), 'defaultCustomOverlaysUrl': Setting(None, 'https://ton-blockchain.github.io/fallback_custom_overlays.json', 'Default custom overlays config url'), + 'debug': Setting(None, False, 'Debug mtc console mode. Prints Traceback on errors'), } diff --git a/modules/controller.py b/modules/controller.py index b9fa78ca..0acc8b1e 100644 --- a/modules/controller.py +++ b/modules/controller.py @@ -48,8 +48,9 @@ def print_controllers_list(self, args): old_controllers = self.ton.GetSettings("old_controllers") user_controllers_list = self.ton.GetSettings("user_controllers_list") print("using controllers:") - self.print_controllers_list_process(using_controllers) - if new_controllers != using_controllers: + if using_controllers is not None: + self.print_controllers_list_process(using_controllers) + if new_controllers is not None and new_controllers != using_controllers: print() print("new controllers:") self.print_controllers_list_process(new_controllers) diff --git a/modules/custom_overlays.py b/modules/custom_overlays.py index e951318c..efa82dd8 100644 --- a/modules/custom_overlays.py +++ b/modules/custom_overlays.py @@ -31,12 +31,20 @@ def parse_config(name: str, config: dict, vset: list = None): "msg_sender": False, }) else: - result["nodes"].append({ - "adnl_id": hex2base64(k), - "msg_sender": v["msg_sender"], - }) - if v["msg_sender"]: - result["nodes"][-1]["msg_sender_priority"] = v["msg_sender_priority"] + if "block_sender" in v: + result["nodes"].append({ + "adnl_id": hex2base64(k), + "block_sender": v["block_sender"], + }) + elif "msg_sender" in v: + result["nodes"].append({ + "adnl_id": hex2base64(k), + "msg_sender": v["msg_sender"], + }) + if v["msg_sender"]: + result["nodes"][-1]["msg_sender_priority"] = v["msg_sender_priority"] + else: + raise Exception("Unknown node type") return result def add_custom_overlay(self, args): @@ -168,7 +176,7 @@ def get_default_custom_overlay(self): network = self.ton.GetNetworkName() default_url = 'https://ton-blockchain.github.io/fallback_custom_overlays.json' url = self.ton.local.db.get('defaultCustomOverlaysUrl', default_url) - resp = requests.get(url) + resp = requests.get(url, timeout=3) if resp.status_code != 200: self.ton.local.add_log(f"Failed to get default custom overlays from {url}", "error") return None diff --git a/modules/nominator_pool.py b/modules/nominator_pool.py index c4f263d2..a5adcc4b 100644 --- a/modules/nominator_pool.py +++ b/modules/nominator_pool.py @@ -56,14 +56,14 @@ def new_pool(self, args): def do_activate_pool(self, pool, ex=True): self.ton.local.add_log("start ActivatePool function", "debug") - for i in range(10): - time.sleep(3) - account = self.ton.GetAccount(pool.addrB64) - if account.balance > 0: - self.ton.SendFile(pool.bocFilePath, pool, timeout=False) - return - if ex: - raise Exception("ActivatePool error: time out") + account = self.ton.GetAccount(pool.addrB64) + if account.status == "empty": + raise Exception("do_activate_pool error: account status is empty") + elif account.status == "active": + self.local.add_log("do_activate_pool warning: account status is active", "warning") + else: + self.ton.SendFile(pool.bocFilePath, pool, timeout=False, remove=False) + #end define def activate_pool(self, args): try: @@ -72,9 +72,6 @@ def activate_pool(self, args): color_print("{red}Bad args. Usage:{endc} activate_pool ") return pool = self.ton.GetLocalPool(pool_name) - if not os.path.isfile(pool.bocFilePath): - self.local.add_log(f"Pool {pool_name} already activated", "warning") - return self.do_activate_pool(pool) color_print("ActivatePool - {green}OK{endc}") diff --git a/modules/single_pool.py b/modules/single_pool.py index 748cc4fd..d2721c5a 100644 --- a/modules/single_pool.py +++ b/modules/single_pool.py @@ -67,6 +67,18 @@ def activate_single_pool(self, args): self.do_activate_single_pool(pool) 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 ") + return + 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")) diff --git a/mypylib b/mypylib index 1d8fd217..049205ee 160000 --- a/mypylib +++ b/mypylib @@ -1 +1 @@ -Subproject commit 1d8fd2172639b7c6d61ded311d2c3a47d60c16b0 +Subproject commit 049205eee1650d7d847497d78acba68c5a33cc37 diff --git a/mytoncore/mytoncore.py b/mytoncore/mytoncore.py index f72f26ba..726b0d2f 100644 --- a/mytoncore/mytoncore.py +++ b/mytoncore/mytoncore.py @@ -497,20 +497,18 @@ def AddrFile2Object(self, object): #end define def WalletVersion2Wallet(self, wallet): - self.local.add_log("start WalletVersion2Wallet function", "debug") if wallet.version is not None: return + self.local.add_log("start WalletVersion2Wallet function", "debug") walletsVersionList = self.GetWalletsVersionList() - account = self.GetAccount(wallet.addrB64) version = walletsVersionList.get(wallet.addrB64) if version is None: + account = self.GetAccount(wallet.addrB64) version = self.GetVersionFromCodeHash(account.codeHash) + self.SetWalletVersion(wallet.addrB64, version) if version is None: self.local.add_log("Wallet version not found: " + wallet.addrB64, "warning") return - #end if - - self.SetWalletVersion(wallet.addrB64, version) wallet.version = version #end define @@ -3047,7 +3045,7 @@ def offers_gc(self, save_offers): def GetSaveOffers(self): bname = "saveOffers" save_offers = self.local.db.get(bname) - if save_offers is None: + if save_offers is None or isinstance(save_offers, list): save_offers = dict() self.local.db[bname] = save_offers self.offers_gc(save_offers) diff --git a/mytonctrl/mytonctrl.py b/mytonctrl/mytonctrl.py index f14f1c0a..9598716f 100755 --- a/mytonctrl/mytonctrl.py +++ b/mytonctrl/mytonctrl.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf_8 -*- +import base64 import subprocess import json import psutil @@ -379,6 +380,14 @@ def Upgrade(ton, args): upgrade_script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/upgrade.sh') runArgs = ["bash", upgrade_script_path, "-a", author, "-r", repo, "-b", branch] exitCode = run_as_root(runArgs) + if ton.using_validator(): + try: + from mytoninstaller.mytoninstaller import set_node_argument, get_node_args + node_args = get_node_args() + if node_args['--state-ttl'] == '604800': + set_node_argument(ton.local, ["--state-ttl", "-d"]) + except Exception as e: + color_print(f"{{red}}Failed to set node argument: {e} {{endc}}") if exitCode == 0: text = "Upgrade - {green}OK{endc}" else: @@ -460,6 +469,10 @@ def check_sync(local, ton): #end define def check_validator_balance(local, ton): + validator_status = ton.GetValidatorStatus() + if not validator_status.is_working or validator_status.out_of_sync >= 20: + # Do not check the validator wallet balance if the node is not synchronized (via public lite-servers) + return if ton.using_validator(): validator_wallet = ton.GetValidatorWallet() validator_account = local.try_function(ton.GetAccount, args=[validator_wallet.addrB64]) @@ -475,6 +488,7 @@ def check_vps(local, ton): data = local.try_function(is_host_virtual) if data and data["virtual"]: color_print(f"Virtualization detected: {data['product_name']}") +#end define def warnings(local, ton): check_disk_usage(local, ton) @@ -544,6 +558,13 @@ def PrintStatus(local, ton, args): disks_load_percent_avg = ton.GetStatistics("disksLoadPercentAvg", statistics) all_status = validator_status.is_working == True and validator_status.out_of_sync < 20 + + try: + vconfig = ton.GetValidatorConfig() + fullnode_adnl = base64.b64decode(vconfig.fullnode).hex().upper() + except: + fullnode_adnl = 'n/a' + if all_status: network_name = ton.GetNetworkName() rootWorkchainEnabledTime_int = ton.GetRootWorkchainEnabledTime() @@ -581,7 +602,7 @@ def PrintStatus(local, ton, args): if all_status: PrintTonStatus(local, network_name, startWorkTime, totalValidators, onlineValidators, shardsNumber, offersNumber, complaintsNumber, tpsAvg) PrintLocalStatus(local, adnl_addr, validator_index, validator_efficiency, validator_wallet, validator_account, validator_status, - db_size, db_usage, memory_info, swap_info, net_load_avg, disks_load_avg, disks_load_percent_avg) + db_size, db_usage, memory_info, swap_info, net_load_avg, disks_load_avg, disks_load_percent_avg, fullnode_adnl) if all_status: PrintTonConfig(local, fullConfigAddr, fullElectorAddr, config15, config17) PrintTimes(local, rootWorkchainEnabledTime_int, startWorkTime, oldStartWorkTime, config15) @@ -631,7 +652,7 @@ def PrintTonStatus(local, network_name, startWorkTime, totalValidators, onlineVa print() #end define -def PrintLocalStatus(local, adnlAddr, validatorIndex, validatorEfficiency, validatorWallet, validatorAccount, validator_status, dbSize, dbUsage, memoryInfo, swapInfo, netLoadAvg, disksLoadAvg, disksLoadPercentAvg): +def PrintLocalStatus(local, adnlAddr, validatorIndex, validatorEfficiency, validatorWallet, validatorAccount, validator_status, dbSize, dbUsage, memoryInfo, swapInfo, netLoadAvg, disksLoadAvg, disksLoadPercentAvg, fullnode_adnl): if validatorWallet is None: return walletAddr = validatorWallet.addrB64 @@ -650,6 +671,7 @@ def PrintLocalStatus(local, adnlAddr, validatorIndex, validatorEfficiency, valid validatorEfficiency_text = GetColorInt(validatorEfficiency, 10, logic="more", ending=" %") validatorEfficiency_text = local.translate("local_status_validator_efficiency").format(validatorEfficiency_text) adnlAddr_text = local.translate("local_status_adnl_addr").format(bcolors.yellow_text(adnlAddr)) + fullnode_adnl_text = local.translate("local_status_fullnode_adnl").format(bcolors.yellow_text(fullnode_adnl)) walletAddr_text = local.translate("local_status_wallet_addr").format(bcolors.yellow_text(walletAddr)) walletBalance_text = local.translate("local_status_wallet_balance").format(bcolors.green_text(walletBalance)) @@ -709,7 +731,9 @@ def PrintLocalStatus(local, adnlAddr, validatorIndex, validatorEfficiency, valid mytoncoreStatus_text = local.translate("local_status_mytoncore_status").format(mytoncoreStatus_color, mytoncoreUptime_text) validatorStatus_text = local.translate("local_status_validator_status").format(validatorStatus_color, validatorUptime_text) validator_out_of_sync_text = local.translate("local_status_validator_out_of_sync").format(GetColorInt(validator_status.out_of_sync, 20, logic="less", ending=" s")) - validator_out_of_ser_text = local.translate("local_status_validator_out_of_ser").format(GetColorInt(validator_status.out_of_ser, 20, logic="less", ending=" blocks")) + + validator_out_of_ser_text = local.translate("local_status_validator_out_of_ser").format(f'{validator_status.out_of_ser} blocks ago') + dbSize_text = GetColorInt(dbSize, 1000, logic="less", ending=" Gb") dbUsage_text = GetColorInt(dbUsage, 80, logic="less", ending="%") dbStatus_text = local.translate("local_status_db").format(dbSize_text, dbUsage_text) @@ -735,6 +759,7 @@ def PrintLocalStatus(local, adnlAddr, validatorIndex, validatorEfficiency, valid print(validatorIndex_text) print(validatorEfficiency_text) print(adnlAddr_text) + print(fullnode_adnl_text) print(walletAddr_text) print(walletBalance_text) print(cpuLoad_text) diff --git a/mytonctrl/resources/translate.json b/mytonctrl/resources/translate.json index 6b3a2823..22c2b283 100644 --- a/mytonctrl/resources/translate.json +++ b/mytonctrl/resources/translate.json @@ -284,6 +284,11 @@ "ru": "ADNL адрес локального валидатора: {0}", "zh_TW": "本地驗證者的 ADNL 地址: {0}" }, + "local_status_fullnode_adnl": { + "en": "Public ADNL address of node: {0}", + "ru": "Публичный ADNL адрес ноды: {0}", + "zh_TW": "節點的公共 ADNL 地址: {0}" + }, "local_status_wallet_addr": { "en": "Local validator wallet address: {0}", "ru": "Адрес кошелька локального валидатора: {0}", @@ -330,9 +335,9 @@ "zh_TW": "本地驗證者不同步: {0}" }, "local_status_validator_out_of_ser": { - "en": "Local validator out of ser: {0}", - "ru": "Рассериализация локального валидатора: {0}", - "zh_TW": "本地驗證者不同步: {0}" + "en": "Local validator last state serialization: {0}", + "ru": "Серализация стейта локального валидатора была: {0}", + "zh_TW": "本地驗證者最後一次狀態序列化: {0}" }, "local_status_db": { "en": "Local validator database size: {0}, {1}", diff --git a/mytoninstaller/settings.py b/mytoninstaller/settings.py index 9f4ca19f..d04c5673 100644 --- a/mytoninstaller/settings.py +++ b/mytoninstaller/settings.py @@ -58,7 +58,7 @@ def FirstNodeSettings(local): # Прописать автозагрузку cpus = psutil.cpu_count() - 1 - cmd = f"{validatorAppPath} --threads {cpus} --daemonize --global-config {globalConfigPath} --db {ton_db_dir} --logname {tonLogPath} --state-ttl 604800 --archive-ttl {archive_ttl} --verbosity 1" + cmd = f"{validatorAppPath} --threads {cpus} --daemonize --global-config {globalConfigPath} --db {ton_db_dir} --logname {tonLogPath} --archive-ttl {archive_ttl} --verbosity 1" add2systemd(name="validator", user=vuser, start=cmd) # post="/usr/bin/python3 /usr/src/mytonctrl/mytoncore.py -e \"validator down\"" # Получить внешний ip адрес