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*