diff --git a/modules/alert_bot.py b/modules/alert_bot.py index 78a8c4a0..e012e77d 100644 --- a/modules/alert_bot.py +++ b/modules/alert_bot.py @@ -76,9 +76,9 @@ def init_alerts(): ), "zero_block_created": Alert( "critical", - f"Validator has not created any blocks in the {int(VALIDATION_PERIOD // 6 // 3600)} hours", + "Validator has not created any blocks in the last few hours", "Validator has not created any blocks in the last {hours} hours.", - VALIDATION_PERIOD // 6 + int(VALIDATION_PERIOD / 2.3) ), "validator_slashed": Alert( "high", @@ -355,7 +355,7 @@ def check_zero_blocks_created(self): if not self.ton.using_validator(): return ts = get_timestamp() - period = VALIDATION_PERIOD // 6 # 3h for mainnet, 40m for testnet + period = int(VALIDATION_PERIOD / 2.3) # ~ 8h for mainnet, 100m for testnet start, end = ts - period, ts - 60 config34 = self.ton.GetConfig34() if start < config34.startWorkTime: # round started recently @@ -364,7 +364,7 @@ def check_zero_blocks_created(self): validator = self.validator_module.find_myself(validators) if validator is None or validator.blocks_created > 0: return - self.send_alert("zero_block_created", hours=round(period // 3600, 1)) + self.send_alert("zero_block_created", hours=round(period / 3600)) def check_slashed(self): if not self.ton.using_validator(): diff --git a/modules/backups.py b/modules/backups.py index 8ea0b2fa..36fb8bd7 100644 --- a/modules/backups.py +++ b/modules/backups.py @@ -6,7 +6,7 @@ import pkg_resources from modules.module import MtcModule -from mypylib.mypylib import color_print, ip2int, run_as_root, parse +from mypylib.mypylib import color_print, ip2int, run_as_root, parse, MyPyClass from mytoninstaller.config import get_own_ip @@ -80,6 +80,10 @@ def restore_backup(self, args): command_args = ["-m", self.ton.local.buffer.my_work_dir, "-n", args[0], "-i", ip] if self.run_restore_backup(command_args) == 0: + self.ton.local.load_db() + if self.ton.using_validator(): + from modules.btc_teleport import BtcTeleportModule + BtcTeleportModule(self.ton, self.local).init(reinstall=True) color_print("restore_backup - {green}OK{endc}") self.local.exit() else: diff --git a/modules/btc_teleport.py b/modules/btc_teleport.py new file mode 100644 index 00000000..bcd0ca25 --- /dev/null +++ b/modules/btc_teleport.py @@ -0,0 +1,230 @@ +import json +import os +import subprocess + +import pkg_resources + +from modules.module import MtcModule +from mypylib.mypylib import run_as_root, color_print, bcolors, print_table + + +class BtcTeleportModule(MtcModule): + + COORDINATOR_ADDRESS = 'Ef_q19o4m94xfF-yhYB85Qe6rTHDX-VTSzxBh4XpAfZMaOvk' + CONFIGURATOR_ADDRESS = 'EQAR_I_lQm5wnEePggUKfioQUFs1vN1YYkK1Kl3WVAPiCzDZ' + + def __init__(self, ton, local, *args, **kwargs): + super().__init__(ton, local, *args, **kwargs) + self.keystore_path = self.ton.local.buffer.my_work_dir + '/btc_oracle_keystore' + self.repo_name = 'ton-teleport-btc-periphery' + self.src_dir = f"/usr/src/{self.repo_name}" + self.bin_dir = self.src_dir + '/out' + + def create_local_file(self): + from mytoninstaller.mytoninstaller import CreateLocalConfigFile + CreateLocalConfigFile(self.local, []) + + def create_env_file(self, reinit=False): + env_path = self.bin_dir + '/.env' + if os.path.exists(env_path) and not reinit: + return + self.create_local_file() + config_path = "/usr/bin/ton/local.config.json" + if not os.path.exists(config_path): + config_path = 'https://ton.org/global-config.json' + warning_text = f""" +WARNING: Could not create local config file. Using global config file ({config_path}). +Please try to create local config file (`mytonctrl <<< "installer clcf"`) and update its path in {env_path} and restart +btc teleport service (`systemctl restart btc_teleport`) or contact validators support. +""" + self.local.add_log(warning_text, 'warning') + text = f""" +COMMON_TON_CONFIG={config_path} +COMMON_TON_CONTRACT_COORDINATOR={self.COORDINATOR_ADDRESS} +ORACLE_STANDALONE_MODE=false +ORACLE_KEYSTORE_PATH={self.keystore_path} +ORACLE_VALIDATOR_ENGINE_CONSOLE_PATH={self.ton.validatorConsole.appPath} +ORACLE_SERVER_PUBLIC_KEY_PATH={self.ton.validatorConsole.pubKeyPath} +ORACLE_CLIENT_PRIVATE_KEY_PATH={self.ton.validatorConsole.privKeyPath} +ORACLE_VALIDATOR_SERVER_ADDR={self.ton.validatorConsole.addr} +ORACLE_DKG_FETCH_PERIOD=15 +ORACLE_EXECUTE_SIGN_PERIOD=15 +ORACLE_SEND_START_DKG_PERIOD=30 +API_CALL_TIMEOUT=15 +LOG_FILE=/var/log/btc_teleport/btc_teleport.log +""" + with open(env_path, 'w') as f: + f.write(text) + + def add_daemon(self): + start = f'{self.bin_dir}/oracle' + script_path = pkg_resources.resource_filename('mytoninstaller', 'scripts/add2systemd.sh') + user = os.environ.get("USER", "root") + run_as_root(['bash', script_path, '-n', 'btc_teleport', '-u', user, '-g', user, '-s', start, '-w', self.bin_dir]) + + def install(self, branch): + script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/btc_teleport1.sh') + exit_code = run_as_root(["bash", script_path, "-s", '/usr/src', "-r", self.repo_name, "-b", branch]) + if exit_code != 0: + raise Exception('Failed to install btc_teleport') + script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/btc_teleport2.sh') + subprocess.run(["bash", script_path, "-s", self.src_dir]) + + def init(self, reinstall=False, branch: str = 'master'): + if os.path.exists(self.src_dir) and not reinstall: + return + self.local.add_log('Installing btc_teleport', 'info') + os.makedirs(self.keystore_path, mode=0o700, exist_ok=True) + self.install(branch) + self.create_env_file() + self.add_daemon() + self.local.add_log('Installed btc_teleport', 'info') + + @staticmethod + def run_remove_btc_teleport(args): + script_path = pkg_resources.resource_filename('mytonctrl', 'scripts/remove_btc_teleport.sh') + return run_as_root(["bash", script_path] + args) + + def get_save_offers(self): + bname = "saveOffersBtcTeleport" + save_offers = self.ton.local.db.get(bname) + if save_offers is None: + save_offers = dict() + self.ton.local.db[bname] = save_offers + return save_offers + + def auto_vote_offers(self): + save_offers = self.get_save_offers() + if not save_offers: + return + current_offers = self.get_offers() + config34 = self.ton.GetConfig34() + for save_offer in list(save_offers.values()): + offer_hash = save_offer['hash'] + if offer_hash not in current_offers: + if save_offer['ttl'] > config34['endWorkTime']: # offer is not expired but not found in current offers, so we assume it has been accepted + save_offers.pop(offer_hash) + self.local.add_log(f'Removing offer {offer_hash} from saved offers', 'debug') + continue + offer = current_offers[save_offer['hash']] + if offer['created_at'] != save_offer['created_at'] and save_offer['ttl'] > config34['endWorkTime']: # offer is not expired but has been changed, so it has been accepted and launched again + save_offers.pop(offer_hash) + self.local.add_log(f'Removing offer {offer_hash} from saved offers', 'debug') + continue + self.vote_offer_btc_teleport([offer_hash]) + + def get_offers(self): + self.local.add_log("start get_offers_btc_teleport function", "debug") + cmd = f"runmethodfull {self.CONFIGURATOR_ADDRESS} list_proposals" + result = self.ton.liteClient.Run(cmd) + raw_offers = self.ton.Result2List(result) + raw_offers = raw_offers[0] + validators = self.ton.GetValidatorsList(fast=True) + total_weight = 0 + for v in validators: + if v['is_masterchain'] is False: + continue + total_weight += v['weight'] + + offers = {} + for offer in raw_offers: + if len(offer) == 0: + continue + item = {} + o_hash = str(offer[0]) + item["hash"] = o_hash + item["remaining_losses"] = offer[1] + item["price"] = offer[2] + item["proposal"] = offer[3] + item["votedValidators"] = offer[4] + weight_remaining = offer[5] + item["weightRemaining"] = weight_remaining + item["vset_id"] = offer[6] + item["creator"] = offer[7] + item["created_at"] = offer[-1] # todo: bug in parsing slice in get method output + required_weight = total_weight * 2 / 3 + if len(item["votedValidators"]) == 0: + weight_remaining = required_weight + available_weight = required_weight - weight_remaining + item["approvedPercent"] = round(available_weight / total_weight * 100, 3) + item["isPassed"] = (weight_remaining < 0) + offers[o_hash] = item + return offers + + def add_save_offer(self, offer: dict): + config15 = self.ton.GetConfig15() + offer['ttl'] = offer['created_at'] + config15['validatorsElectedFor'] * 3 # proposal lives 3 rounds + self.get_save_offers()[offer['hash']] = offer + self.ton.local.save() + + def vote_offer_btc_teleport(self, args): + if len(args) == 0: + color_print("{red}Bad args. Usage:{endc} vote_offer_btc_teleport [offer-hash-2 offer-hash-3 ...]") + return + wallet = self.ton.GetValidatorWallet(mode="vote") + validator_key = self.ton.GetValidatorKey() + validator_pubkey_b64 = self.ton.GetPubKeyBase64(validator_key) + validator_index = self.ton.GetValidatorIndex() + config34 = self.ton.GetConfig34() + if validator_index == -1 or validator_index >= config34['mainValidators']: + self.local.add_log("Can not vote for BTC Teleport proposal from non-masterchain validator", "error") + return + for offer_hash in args: + current_offers = self.get_offers() + if offer_hash not in current_offers: + self.local.add_log("Offer not found, skip", "warning") + return + offer = current_offers[offer_hash] + if validator_index in offer.get("votedValidators"): + self.local.add_log("Proposal already has been voted", "debug") + return + self.add_save_offer(offer) + request_hash = self.ton.CreateConfigProposalRequest(offer_hash, validator_index) + validator_signature = self.ton.GetValidatorSignature(validator_key, request_hash) + path = self.ton.SignProposalVoteRequestWithValidator(offer_hash, validator_index, validator_pubkey_b64, + validator_signature) + path = self.ton.SignBocWithWallet(wallet, path, self.CONFIGURATOR_ADDRESS, 1.5) + self.ton.SendFile(path, wallet) + + def print_offers_btc_teleport_list(self, args): + data = self.get_offers() + if not data: + print("No data") + return + if "--json" in args: + text = json.dumps(data, indent=2) + print(text) + return + table = [["Hash", "Votes", "Approved", "Is passed"]] + for item in data.values(): + o_hash = item.get("hash") + voted_validators = len(item.get("votedValidators")) + approved_percent_text = f"{item.get('approvedPercent')}%" + is_passed = item.get("isPassed") + if "hash" not in args: + from modules.utilities import UtilitiesModule + o_hash = UtilitiesModule.reduct(o_hash) + if is_passed is True: + is_passed = bcolors.green_text("true") + if is_passed is False: + is_passed = bcolors.red_text("false") + table += [[o_hash, voted_validators, approved_percent_text, is_passed]] + print_table(table) + + def remove_btc_teleport(self, args: list): + if len(args) > 1: + color_print("{red}Bad args. Usage:{endc} remove_btc_teleport [--force]") + return + if '--force' not in args: + if -1 < self.ton.GetValidatorIndex() < self.ton.GetConfig34()['mainValidators']: + self.local.add_log('You can not remove btc_teleport on working masterchain validator', 'error') + return + exit_code = self.run_remove_btc_teleport(["-s", self.src_dir, "-k", self.keystore_path]) + if exit_code != 0: + raise Exception('Failed to remove btc_teleport') + 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")) + console.AddItem("vote_offer_btc_teleport", self.vote_offer_btc_teleport, self.local.translate("vote_offer_btc_teleport_cmd")) + console.AddItem("print_offers_btc_teleport_list", self.print_offers_btc_teleport_list, self.local.translate("print_offers_btc_teleport_list_cmd")) diff --git a/modules/module.py b/modules/module.py index b1ce709a..7d9a185a 100644 --- a/modules/module.py +++ b/modules/module.py @@ -1,5 +1,7 @@ from abc import ABC, abstractmethod +from mypylib.mypylib import MyPyClass + class MtcModule(ABC): @@ -9,7 +11,7 @@ class MtcModule(ABC): def __init__(self, ton, local, *args, **kwargs): from mytoncore.mytoncore import MyTonCore self.ton: MyTonCore = ton - self.local = local + self.local: MyPyClass = local @abstractmethod def add_console_commands(self, console): ... diff --git a/mytoncore/functions.py b/mytoncore/functions.py index 7e909c61..da3cef38 100755 --- a/mytoncore/functions.py +++ b/mytoncore/functions.py @@ -55,6 +55,8 @@ def Event(local, event_name): ValidatorDownEvent(local) elif event_name.startswith("enable_mode"): enable_mode(local, event_name) + elif event_name == "enable_btc_teleport": + enable_btc_teleport(local) local.exit() # end define @@ -90,6 +92,10 @@ def enable_mode(local, event_name): ton.enable_mode(mode) #end define +def enable_btc_teleport(local): + ton = MyTonCore(local) + from modules.btc_teleport import BtcTeleportModule + BtcTeleportModule(ton, local).init(reinstall=True) def Elections(local, ton): use_pool = ton.using_pool() @@ -679,6 +685,9 @@ def General(local): from modules.prometheus import PrometheusModule local.start_cycle(PrometheusModule(ton, local).push_metrics, sec=30, args=()) + from modules.btc_teleport import BtcTeleportModule + local.start_cycle(BtcTeleportModule(ton, local).auto_vote_offers, sec=180, args=()) + if ton.in_initial_sync(): local.start_cycle(check_initial_sync, sec=120, args=(local, ton)) diff --git a/mytoncore/mytoncore.py b/mytoncore/mytoncore.py index 1240b311..30757ee5 100644 --- a/mytoncore/mytoncore.py +++ b/mytoncore/mytoncore.py @@ -12,6 +12,7 @@ from fastcrc import crc16 from modules import MODES +from modules.btc_teleport import BtcTeleportModule from mytoncore.utils import xhex2hex, ng2g from mytoncore.liteclient import LiteClient from mytoncore.validator_console import ValidatorConsole @@ -818,7 +819,7 @@ def GetValidatorStatus(self, no_cache=False): status.out_of_sync = status.masterchain_out_of_sync if status.masterchain_out_of_sync > status.shardchain_out_of_sync else status.shardchain_out_of_sync status.out_of_ser = status.masterchain_out_of_ser status.last_deleted_mc_state = int(parse(result, "last_deleted_mc_state", '\n')) - status.stateserializerenabled = parse(result, "stateserializerenabled", '\n') == "true" + status.stateserializerenabled = parse(result, "stateserializerenabled", '\n').strip() == "true" self.local.try_function(self.parse_stats_from_vc, args=[result, status]) if 'active_validator_groups' in status: groups = status.active_validator_groups.split() # master:1 shard:2 @@ -2511,7 +2512,7 @@ def GetValidatorsList(self, past=False, fast=False, start=None, end=None): end = timestamp - 60 if start is None: if fast: - start = end - 1000 + start = max(end - 1000, config.get("startWorkTime")) else: start = config.get("startWorkTime") if past: @@ -3150,6 +3151,7 @@ def check_enable_mode(self, name): if self.using_liteserver(): raise Exception(f'Cannot enable validator mode while liteserver mode is enabled. ' f'Use `disable_mode liteserver` first.') + BtcTeleportModule(self, self.local).init() if name == 'liquid-staking': from mytoninstaller.settings import enable_ton_http_api enable_ton_http_api(self.local) diff --git a/mytonctrl/mytonctrl.py b/mytonctrl/mytonctrl.py index 7165ebe5..21671da6 100755 --- a/mytonctrl/mytonctrl.py +++ b/mytonctrl/mytonctrl.py @@ -100,6 +100,10 @@ def inject_globals(func): module = CustomOverlayModule(ton, local) module.add_console_commands(console) + from modules.btc_teleport import BtcTeleportModule + module = BtcTeleportModule(ton, local) + module.add_console_commands(console) + if ton.using_validator(): from modules.validator import ValidatorModule module = ValidatorModule(ton, local) @@ -326,7 +330,11 @@ def Update(local, args): local.exit() #end define -def Upgrade(ton, args): +def Upgrade(local, ton, args: list): + if '--btc-teleport' in args: # upgrade --btc-teleport [branch] + branch = args[args.index('--btc-teleport') + 1] if len(args) > args.index('--btc-teleport') + 1 else 'master' + upgrade_btc_teleport(local, ton, reinstall=True, branch=branch) + return repo = "ton" author, repo, branch = check_git(args, repo, "upgrade") @@ -360,6 +368,8 @@ 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(): + upgrade_btc_teleport(local, ton) if exitCode == 0: text = "Upgrade - {green}OK{endc}" else: @@ -367,6 +377,13 @@ def Upgrade(ton, args): color_print(text) #end define + +def upgrade_btc_teleport(local, ton, reinstall=False, branch: str = 'master'): + from modules.btc_teleport import BtcTeleportModule + module = BtcTeleportModule(ton, local) + local.try_function(module.init, args=[reinstall, branch]) + + def get_clang_major_version(): try: process = subprocess.run(["clang", "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -397,6 +414,7 @@ def get_clang_major_version(): print(f"Error checking clang version: {type(e)}: {e}") return None + def rollback_to_mtc1(local, ton, args): color_print("{red}Warning: this is dangerous, please make sure you've backed up mytoncore's db.{endc}") a = input("Do you want to continue? [Y/n]\n") @@ -525,6 +543,7 @@ def warnings(local, ton): local.try_function(check_slashed, args=[local, ton]) #end define + def CheckTonUpdate(local): git_path = "/usr/src/ton" result = check_git_update(git_path) @@ -752,6 +771,14 @@ def PrintLocalStatus(local, ton, adnlAddr, validatorIndex, validatorEfficiency, validatorStatus_color = GetColorStatus(validatorStatus_bool) 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) + btc_teleport_status_text = None + if ton.using_validator(): + btc_teleport_status_bool = get_service_status("btc_teleport") + btc_teleport_status_uptime = get_service_uptime("btc_teleport") + btc_teleport_status_text = local.translate("local_status_btc_teleport_status").format( + GetColorStatus(btc_teleport_status_bool), + bcolors.green_text(time2human(btc_teleport_status_uptime)) if btc_teleport_status_bool else 'n/a' + ) validator_initial_sync_text = '' validator_out_of_sync_text = '' @@ -802,8 +829,18 @@ def PrintLocalStatus(local, ton, adnlAddr, validatorIndex, validatorEfficiency, mtcGitPath = "/usr/src/mytonctrl" validatorGitPath = "/usr/src/ton" validatorBinGitPath = "/usr/bin/ton/validator-engine/validator-engine" + btc_teleport_path = "/usr/src/ton-teleport-btc-periphery/" mtcGitHash = get_git_hash(mtcGitPath, short=True) validatorGitHash = GetBinGitHash(validatorBinGitPath, short=True) + btc_teleport_git_hash = None + btc_teleport_git_branch = None + if ton.using_validator(): + if os.path.exists(btc_teleport_path): + btc_teleport_git_hash = get_git_hash(btc_teleport_path, short=True) + btc_teleport_git_branch = get_git_branch(btc_teleport_path) + else: + btc_teleport_git_hash = "n/a" + btc_teleport_git_branch = "n/a" fix_git_config(mtcGitPath) fix_git_config(validatorGitPath) mtcGitBranch = get_git_branch(mtcGitPath) @@ -814,6 +851,11 @@ def PrintLocalStatus(local, ton, adnlAddr, validatorIndex, validatorEfficiency, validatorGitBranch_text = bcolors.yellow_text(validatorGitBranch) mtcVersion_text = local.translate("local_status_version_mtc").format(mtcGitHash_text, mtcGitBranch_text) validatorVersion_text = local.translate("local_status_version_validator").format(validatorGitHash_text, validatorGitBranch_text) + btc_teleport_version_text = None + if btc_teleport_git_hash: + btc_teleport_git_hash_text = bcolors.yellow_text(btc_teleport_git_hash) + btc_teleport_git_branch_text = bcolors.yellow_text(btc_teleport_git_branch) + btc_teleport_version_text = local.translate("local_status_version_teleport").format(btc_teleport_git_hash_text, btc_teleport_git_branch_text) color_print(local.translate("local_status_head")) node_ip = ton.get_validator_engine_ip() @@ -837,6 +879,8 @@ def PrintLocalStatus(local, ton, adnlAddr, validatorIndex, validatorEfficiency, print(mytoncoreStatus_text) if not is_node_remote: print(validatorStatus_text) + if btc_teleport_status_text: + print(btc_teleport_status_text) if validator_initial_sync_text: print(validator_initial_sync_text) if validator_out_of_sync_text: @@ -855,6 +899,8 @@ def PrintLocalStatus(local, ton, adnlAddr, validatorIndex, validatorEfficiency, print(dbStatus_text) print(mtcVersion_text) print(validatorVersion_text) + if btc_teleport_version_text: + print(btc_teleport_version_text) print() #end define diff --git a/mytonctrl/resources/translate.json b/mytonctrl/resources/translate.json index 70cbccca..e9823839 100644 --- a/mytonctrl/resources/translate.json +++ b/mytonctrl/resources/translate.json @@ -139,6 +139,16 @@ "ru": "Голосовать за предложение", "zh_TW": "投票支持優惠" }, + "vote_offer_btc_teleport_cmd": { + "en": "Vote for BTC teleport proposal", + "ru": "Голосовать за предложение BTC Teleport", + "zh_TW": "投票支持 BTC Teleport 優惠" + }, + "print_offers_btc_teleport_list_cmd": { + "en": "Show BTC teleport proposals list", + "ru": "Показать список предложений BTC Teleport", + "zh_TW": "顯示 BTC Teleport 優惠列表" + }, "od_cmd": { "en": "Show offer diff", "ru": "Показать разницу предложений", @@ -319,6 +329,11 @@ "ru": "Статус локального валидатора: {0}, {1}", "zh_TW": "本地驗證者狀態: {0}, {1}" }, + "local_status_btc_teleport_status": { + "en": "BTC Teleport status: {0}, {1}", + "ru": "Статус BTC Teleport: {0}, {1}", + "zh_TW": "BTC Teleport 狀態: {0}, {1}" + }, "local_status_validator_initial_sync": { "en": "Local validator initial sync status: {0}", "ru": "Статус начальной синхронизации локального валидатора: {0}", @@ -379,6 +394,11 @@ "ru": "Версия валидатора: {0} ({1})", "zh_TW": "驗證者版本: {0} ({1})" }, + "local_status_version_teleport": { + "en": "Version BTC Teleport: {0} ({1})", + "ru": "Версия BTC Teleport: {0} ({1})", + "zh_TW": "BTC Teleport 版本: {0} ({1})" + }, "ton_config_head": { "en": "{cyan}===[ TON network configuration ]==={endc}", "ru": "{cyan}===[ Конфигурация сети TON ]==={endc}", @@ -534,6 +554,11 @@ "ru": "Настроить Telegram Bot для оповещений", "zh_TW": "設置 Telegram Bot 以接收警報" }, + "remove_btc_teleport_cmd": { + "en": "Remove BTC Teleport Oracle", + "ru": "Удалить BTC Teleport Oracle", + "zh_TW": "刪除 BTC Teleport Oracle" + }, "benchmark_cmd": { "en": "Run benchmark", "ru": "Запустить бенчмарк", diff --git a/mytonctrl/scripts/btc_teleport1.sh b/mytonctrl/scripts/btc_teleport1.sh new file mode 100644 index 00000000..94c88db7 --- /dev/null +++ b/mytonctrl/scripts/btc_teleport1.sh @@ -0,0 +1,42 @@ +REPO="" +SRC_DIR="" +USER=$(logname) +BRANCH=master + +while getopts s:r:b: flag +do + case "${flag}" in + s) SRC_DIR=${OPTARG};; + r) REPO=${OPTARG};; + b) BRANCH=${OPTARG};; + *) echo "Flag -${flag} is not recognized. Aborting"; exit 1 ;; + esac +done + +# install go +GO_BIN_PATH=/usr/local/go/bin/go +if [ ! -f $GO_BIN_PATH ] || { [ -f $GO_BIN_PATH ] && [[ "$($GO_BIN_PATH version)" != *"1.23.1"* ]]; }; then + wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz + rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz && rm go1.23.1.linux-amd64.tar.gz + echo installed go 1.23.1 +fi + + +# clone repo + +REPO_URL=https://github.com/RSquad/${REPO}.git + +cd $SRC_DIR || exit 1 +rm -rf $REPO +git clone $REPO_URL +cd $REPO && git checkout $BRANCH +cd .. + +chown -R $USER:$USER $REPO + +git config --global --add safe.directory $SRC_DIR/$REPO + +echo "oracle sources cloned successfully" + +mkdir -p /var/log/btc_teleport +chown -R $USER:$USER /var/log/btc_teleport diff --git a/mytonctrl/scripts/btc_teleport2.sh b/mytonctrl/scripts/btc_teleport2.sh new file mode 100644 index 00000000..6f314d13 --- /dev/null +++ b/mytonctrl/scripts/btc_teleport2.sh @@ -0,0 +1,39 @@ +SRC_DIR="" + +while getopts s: flag +do + case "${flag}" in + s) SRC_DIR=${OPTARG};; + *) echo "Flag -${flag} is not recognized. Aborting"; exit 1 ;; + esac +done + +# install rust +if ! command -v rustc >/dev/null 2>&1 +then + echo "installing rust" + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rust.sh && bash /tmp/rust.sh -y + rm /tmp/rust.sh + . "$HOME/.cargo/env" + echo "installed rust" +fi + +cargo install cbindgen + +# build frost + +cd $SRC_DIR/frost || exit 1 + +cd rust +./build.sh +cd .. + +/usr/local/go/bin/go build . +/usr/local/go/bin/go test -v || exit 1 + +echo "frost built successfully" + +cd $SRC_DIR +/usr/local/go/bin/go build -o out/oracle ./oracle/cmd/main.go + +echo "oracle built successfully" diff --git a/mytonctrl/scripts/remove_btc_teleport.sh b/mytonctrl/scripts/remove_btc_teleport.sh new file mode 100644 index 00000000..b9f7fbe7 --- /dev/null +++ b/mytonctrl/scripts/remove_btc_teleport.sh @@ -0,0 +1,18 @@ +SRC_DIR="" +KEYSTORE_PATH="" + +while getopts s:k: flag +do + case "${flag}" in + s) SRC_DIR=${OPTARG};; + k) KEYSTORE_PATH=${OPTARG};; + *) echo "Flag -${flag} is not recognized. Aborting"; exit 1 ;; + esac +done + + +rm -rf $KEYSTORE_PATH +rm -rf $SRC_DIR +systemctl stop btc_teleport +rm -rf /etc/systemd/system/btc_teleport.service +systemctl daemon-reload \ No newline at end of file diff --git a/mytoninstaller/mytoninstaller.py b/mytoninstaller/mytoninstaller.py index 6bfcb5fb..285efd3d 100644 --- a/mytoninstaller/mytoninstaller.py +++ b/mytoninstaller/mytoninstaller.py @@ -15,7 +15,7 @@ from mytoninstaller.config import GetLiteServerConfig, get_ls_proxy_config from mytoninstaller.node_args import get_node_args from mytoninstaller.utils import GetInitBlock -from mytoncore.utils import dict2b64, str2bool, b642dict +from mytoncore.utils import dict2b64, str2bool, b642dict, b642hex from mytoninstaller.settings import ( FirstNodeSettings, @@ -196,10 +196,19 @@ def PrintLiteServerConfig(local, args): def CreateLocalConfigFile(local, args): - initBlock = GetInitBlock() - initBlock_b64 = dict2b64(initBlock) + init_block = GetInitBlock() + if init_block['rootHash'] is None: + local.add_log("Failed to get recent init block. Using init block from global config.", "warning") + with open('/usr/bin/ton/global.config.json', 'r') as f: + config = json.load(f) + config_init_block = config['validator']['init_block'] + init_block = dict() + init_block["seqno"] = config_init_block['seqno'] + init_block["rootHash"] = b642hex(config_init_block['root_hash']) + init_block["fileHash"] = b642hex(config_init_block['file_hash']) + init_block_b64 = dict2b64(init_block) user = local.buffer.user or os.environ.get("USER", "root") - args = ["python3", "-m", "mytoninstaller", "-u", user, "-e", "clc", "-i", initBlock_b64] + args = ["python3", "-m", "mytoninstaller", "-u", user, "-e", "clc", "-i", init_block_b64] run_as_root(args) #end define diff --git a/mytoninstaller/scripts/add2systemd.sh b/mytoninstaller/scripts/add2systemd.sh index 13626522..e8c8b5f8 100755 --- a/mytoninstaller/scripts/add2systemd.sh +++ b/mytoninstaller/scripts/add2systemd.sh @@ -11,7 +11,7 @@ post="/bin/echo service down" user=root group=root -while getopts n:s:p:u:g: flag +while getopts n:s:p:u:g:w: flag do case "${flag}" in n) name=${OPTARG};; @@ -19,6 +19,7 @@ do p) post=${OPTARG};; u) user=${OPTARG};; g) group=${OPTARG};; + w) workdir=${OPTARG};; esac done @@ -37,7 +38,7 @@ DAEMON_PATH="/etc/systemd/system/${name}.service" cat < $DAEMON_PATH [Unit] -Description = $name service. Created by https://github.com/igroman787/mypylib. +Description = $name service. After = network.target [Service] @@ -48,6 +49,7 @@ ExecStart = $start ExecStopPost = $post User = $user Group = $group +WorkingDirectory = $workdir LimitNOFILE = infinity LimitNPROC = infinity LimitMEMLOCK = infinity @@ -60,3 +62,4 @@ chmod 664 $DAEMON_PATH chmod +x $DAEMON_PATH systemctl daemon-reload systemctl enable ${name} +systemctl restart ${name} diff --git a/mytoninstaller/scripts/jsonrpcinstaller.sh b/mytoninstaller/scripts/jsonrpcinstaller.sh index 926d61e1..32476729 100755 --- a/mytoninstaller/scripts/jsonrpcinstaller.sh +++ b/mytoninstaller/scripts/jsonrpcinstaller.sh @@ -43,7 +43,6 @@ echo -e "${COLOR}[3/4]${ENDC} Add to startup" SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) echo "Script dir: ${SCRIPT_DIR}" ${SCRIPT_DIR}/add2systemd.sh -n mtc-jsonrpc -s "/usr/bin/python3 /usr/src/mtc-jsonrpc/mtc-jsonrpc.py" -u ${user} -g ${user} -systemctl restart mtc-jsonrpc # Выход из программы echo -e "${COLOR}[4/4]${ENDC} JsonRPC installation complete" diff --git a/mytoninstaller/settings.py b/mytoninstaller/settings.py index a9256eee..7d352223 100644 --- a/mytoninstaller/settings.py +++ b/mytoninstaller/settings.py @@ -1099,7 +1099,7 @@ def CreateSymlinks(local): def EnableMode(local): args = ["python3", "-m", "mytoncore", "-e"] - if local.buffer.mode and local.buffer.mode != "none": + if local.buffer.mode and local.buffer.mode != "none" and not local.buffer.backup: args.append("enable_mode_" + local.buffer.mode) else: return @@ -1146,6 +1146,10 @@ def ConfigureFromBackup(local): return set_external_ip(local, node_ip) + args = ["python3", "-m", "mytoncore", "-e", "enable_btc_teleport"] + args = ["su", "-l", local.buffer.user, "-c", ' '.join(args)] + subprocess.run(args) + def ConfigureOnlyNode(local): if not local.buffer.only_node: diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 9e1f275c..6da3f8c8 100644 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -20,6 +20,7 @@ ENDC='\033[0m' systemctl stop validator systemctl stop mytoncore systemctl stop dht-server +systemctl stop btc_teleport # Переменные str=$(systemctl cat mytoncore | grep User | cut -d '=' -f2) @@ -29,6 +30,7 @@ user=$(echo ${str}) rm -rf /etc/systemd/system/validator.service rm -rf /etc/systemd/system/mytoncore.service rm -rf /etc/systemd/system/dht-server.service +rm -rf /etc/systemd/system/btc_teleport.service systemctl daemon-reload # Удаление файлов @@ -41,6 +43,7 @@ if $full; then fi rm -rf /usr/src/mytonctrl +rm -rf /usr/src/ton-teleport-btc-periphery rm -rf /usr/src/mtc-jsonrpc rm -rf /usr/src/pytonv3 rm -rf /tmp/myton*