diff --git a/custom_overlays.py b/custom_overlays.py new file mode 100644 index 00000000..c6fbcdb3 --- /dev/null +++ b/custom_overlays.py @@ -0,0 +1,124 @@ +import json + +from mypylib.mypylib import color_print +from mytoncore import local as mytoncore_local, hex2base64, MyTonCore +from mytonctrl import ton + + +def parse_config(name: str, config: dict, vset: list = None): + """ + Converts config to validator-console friendly format + :param name: custom overlay name + :param config: config + :param vset: list of validators adnl addresses, can be None if `@validators` not in config + :return: + """ + result = { + "name": name, + "nodes": [] + } + for k, v in config.items(): + result["nodes"].append({ + "adnl_id": hex2base64(k), + "msg_sender": v["msg_sender"], + "msg_sender_priority": v["msg_sender_priority"], + }) + if k == '@validators' and v: + if vset is None: + raise Exception("Validators set is not defined but @validators is in config") + for v_adnl in vset: + result["nodes"].append({ + "adnl_id": hex2base64(v_adnl), + "msg_sender": False, + }) + return result + + +def add_custom_overlay(args): + if len(args) != 2: + color_print("{red}Bad args. Usage:{endc} add_custom_overlay ") + return + path = args[1] + with open(path, 'r') as f: + config = json.load(f) + mytoncore_local.db['custom_overlays'][args[0]] = config + + +def list_custom_overlays(args): + for k, v in mytoncore_local.db['custom_overlays'].items(): + color_print(f"Custom overlay {{bold}}{k}{{endc}}:") + print(json.dumps(v, indent=4)) + + +def delete_custom_overlay(args): + if len(args) != 1: + color_print("{red}Bad args. Usage:{endc} delete_custom_overlay ") + return + del mytoncore_local.db['custom_overlays'][args[0]] + + +def delete_custom_overlay_from_vc(name: str): + result = ton.validatorConsole.Run(f"delcustomoverlay {name}") + return 'success' in result + + +def add_custom_overlay_to_vc(config: dict): + mytoncore_local.add_log(f"Adding custom overlay {config['name']}", "debug") + path = ton.tempDir + f'/custom_overlay_{config["name"]}.json' + with open(path, 'w') as f: + json.dump(config, f) + result = ton.validatorConsole.Run(f"addcustomoverlay {path}") + return 'success' in result + + +def deploy_custom_overlays(): + result = ton.validatorConsole.Run("showcustomoverlays") + if 'unknown command' in result: + return # node old version + names = [] + for line in result.split('\n'): + if line.startswith('Overlay'): + names.append(line.split(' ')[1].replace('"', '')) + + config34 = ton.GetConfig34() + current_el_id = config34['startWorkTime'] + current_vset = [i["adnlAddr"] for i in config34['validators']] + + config36 = ton.GetConfig36() + next_el_id = config36['startWorkTime'] if config36['validators'] else 0 + next_vset = [i["adnlAddr"] for i in config36['validators']] + + for name in names: + # check that overlay still exists in mtc db + pure_name = name + suffix = name.split('_')[-1] + if suffix.startswith('elid') and suffix.split('elid')[-1].isdigit(): # probably election id + pure_name = '_'.join(name.split('_')[:-1]) + el_id = int(suffix.split('elid')[-1].isdigit()) + if el_id not in (current_el_id, next_el_id): + mytoncore_local.add_log(f"Overlay {name} is not in current or next election, deleting", "debug") + delete_custom_overlay_from_vc(name) # delete overlay if election id is not in current or next election + continue + + if pure_name not in mytoncore_local.db['custom_overlays']: + mytoncore_local.add_log(f"Overlay {name} is not in mtc db, deleting", "debug") + delete_custom_overlay_from_vc(name) # delete overlay if it's not in mtc db + + for name, config in mytoncore_local.db['custom_overlays'].items(): + if name in names: + continue + if '@validators' in config: + new_name = name + '_elid' + str(current_el_id) + if new_name not in names: + node_config = parse_config(new_name, config, current_vset) + add_custom_overlay_to_vc(node_config) + + if next_el_id != 0: + new_name = name + '_elid' + str(next_el_id) + if new_name not in names: + node_config = parse_config(new_name, config, next_vset) + add_custom_overlay_to_vc(node_config) + else: + + node_config = parse_config(name, config) + add_custom_overlay_to_vc(node_config) diff --git a/mytoncore.py b/mytoncore.py index 82572b5b..cf19e348 100755 --- a/mytoncore.py +++ b/mytoncore.py @@ -8,6 +8,7 @@ import requests import re from mypylib.mypylib import * +from custom_overlays import deploy_custom_overlays local = MyPyClass(__file__) @@ -4297,6 +4298,7 @@ def General(): local.start_cycle(Telemetry, sec=60, args=(ton, )) local.start_cycle(OverlayTelemetry, sec=7200, args=(ton, )) local.start_cycle(ScanLiteServers, sec=60, args=(ton,)) + local.start_cycle(deploy_custom_overlays, sec=60) thr_sleep() #end define diff --git a/mytonctrl.py b/mytonctrl.py index 09a91834..6549afcd 100755 --- a/mytonctrl.py +++ b/mytonctrl.py @@ -4,6 +4,7 @@ from mypylib.mypylib import * from mypyconsole.mypyconsole import * from mytoncore import * +from custom_overlays import add_custom_overlay, list_custom_overlays, delete_custom_overlay import sys, getopt, os local = MyPyClass(__file__) @@ -25,6 +26,10 @@ def Init(argv): console.AddItem("seqno", Seqno, local.translate("seqno_cmd")) console.AddItem("getconfig", GetConfig, local.translate("getconfig_cmd")) + console.AddItem("add_custom_overlay", add_custom_overlay, local.translate("add_custom_overlay_cmd")) + console.AddItem("list_custom_overlays", list_custom_overlays, local.translate("list_custom_overlays_cmd")) + console.AddItem("delete_custom_overlay", delete_custom_overlay, local.translate("delete_custom_overlay_cmd")) + console.AddItem("nw", CreatNewWallet, local.translate("nw_cmd")) console.AddItem("aw", ActivateWallet, local.translate("aw_cmd")) console.AddItem("wl", PrintWalletsList, local.translate("wl_cmd"))