Skip to content

Commit f28a021

Browse files
authored
Merge pull request #232 from ton-blockchain/mytonctrl2_dev
merge mytonctrl2_dev into mytonctrl2
2 parents aff9b73 + 99d8c92 commit f28a021

19 files changed

+839
-161
lines changed

docs/ru/ton-storage-provider.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# TON storage provider
2+
3+
MyTonCtrl поддерживает установку дополнительных компонентов таких как `TON storage` и `TON storage provider`. С их помощью вы можете хранить пользовательские файлы у себя на сервере и получать за это вознаграждение.
4+
5+
## Установка дополнительных компонентов
6+
7+
Войдите в MyTonCtrl
8+
```
9+
mytonctrl
10+
```
11+
12+
Затем войдите в режим установщика
13+
```
14+
installer
15+
```
16+
17+
После включите нужный функционал TON storage provider:
18+
```
19+
enable TSP
20+
```
21+
22+
## Активация контракта провайдера
23+
24+
В ходе установки дополнительных компонетов был создан специальный кошелек провайдера `provider_wallet_001` откуда будут отправляться доказательства и куда будет приходить награда.
25+
Для его работы сначала нужно пополнить этот кошелек на 1 монету и активировать его командой внутри MyTonCtrl, в ходе которого он так же зарегистрируется в списке провайдеров:
26+
```
27+
activate_ton_storage_provider
28+
```
29+
30+
## Панель управления TON storage provider
31+
32+
TODO

modules/nominator_pool.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,37 @@
77

88
class NominatorPoolModule(PoolModule):
99

10+
def do_create_pool(self, pool_name, validator_reward_share_percent, max_nominators_count, min_validator_stake,
11+
min_nominator_stake):
12+
self.ton.local.add_log("start CreatePool function", "debug")
13+
validator_reward_share = int(validator_reward_share_percent * 100)
14+
15+
self.check_download_pool_contract_scripts()
16+
17+
file_path = self.ton.poolsDir + pool_name
18+
if os.path.isfile(file_path + ".addr"):
19+
self.ton.local.add_log("CreatePool warning: Pool already exists: " + file_path, "warning")
20+
return
21+
# end if
22+
23+
fift_script = self.ton.contractsDir + "nominator-pool/func/new-pool.fif"
24+
wallet = self.ton.GetValidatorWallet()
25+
args = [fift_script, wallet.addrB64, validator_reward_share, max_nominators_count, min_validator_stake,
26+
min_nominator_stake, file_path]
27+
result = self.ton.fift.Run(args)
28+
if "Saved pool" not in result:
29+
raise Exception("CreatePool error: " + result)
30+
# end if
31+
32+
pools = self.ton.GetPools()
33+
new_pool = self.ton.GetLocalPool(pool_name)
34+
for pool in pools:
35+
if pool.name != new_pool.name and pool.addrB64 == new_pool.addrB64:
36+
new_pool.Delete()
37+
raise Exception("CreatePool error: Pool with the same parameters already exists.")
38+
# end for
39+
# end define
40+
1041
def new_pool(self, args):
1142
try:
1243
pool_name = args[0]
@@ -17,7 +48,7 @@ def new_pool(self, args):
1748
except:
1849
color_print("{red}Bad args. Usage:{endc} new_pool <pool-name> <validator-reward-share-percent> <max-nominators-count> <min-validator-stake> <min-nominator-stake>")
1950
return
20-
self.ton.CreatePool(pool_name, validator_reward_share_percent, max_nominators_count, min_validator_stake, min_nominator_stake)
51+
self.do_create_pool(pool_name, validator_reward_share_percent, max_nominators_count, min_validator_stake, min_nominator_stake)
2152
color_print("NewPool - {green}OK{endc}")
2253

2354
def do_activate_pool(self, pool, ex=True):

modules/pool.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from mypylib.mypylib import color_print, print_table
24
from modules.module import MtcModule
35

@@ -28,6 +30,15 @@ def delete_pool(self, args):
2830
pool = self.ton.GetLocalPool(pool_name)
2931
pool.Delete()
3032
color_print("DeletePool - {green}OK{endc}")
33+
# end define
34+
35+
def do_import_pool(self, pool_name, addr_b64):
36+
self.check_download_pool_contract_scripts()
37+
addr_bytes = self.ton.addr_b64_to_bytes(addr_b64)
38+
pool_path = self.ton.poolsDir + pool_name
39+
with open(pool_path + ".addr", 'wb') as file:
40+
file.write(addr_bytes)
41+
# end define
3142

3243
def import_pool(self, args):
3344
try:
@@ -36,9 +47,14 @@ def import_pool(self, args):
3647
except:
3748
color_print("{red}Bad args. Usage:{endc} import_pool <pool-name> <pool-addr>")
3849
return
39-
self.ton.import_pool(pool_name, pool_addr)
50+
self.do_import_pool(pool_name, pool_addr)
4051
color_print("import_pool - {green}OK{endc}")
4152

53+
def check_download_pool_contract_scripts(self):
54+
contract_path = self.ton.contractsDir + "nominator-pool/"
55+
if not os.path.isdir(contract_path):
56+
self.ton.DownloadContract("https://github.com/ton-blockchain/nominator-pool")
57+
4258
def add_console_commands(self, console):
4359
console.AddItem("pools_list", self.print_pools_list, self.local.translate("pools_list_cmd"))
4460
console.AddItem("delete_pool", self.delete_pool, self.local.translate("delete_pool_cmd"))

modules/single_pool.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class SingleNominatorModule(PoolModule):
1111
def do_create_single_pool(self, pool_name, owner_address):
1212
self.ton.local.add_log("start create_single_pool function", "debug")
1313

14+
self.check_download_pool_contract_scripts()
15+
1416
file_path = self.ton.poolsDir + pool_name
1517
if os.path.isfile(file_path + ".addr"):
1618
self.ton.local.add_log("create_single_pool warning: Pool already exists: " + file_path, "warning")

mytoncore/functions.py

Lines changed: 110 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
import psutil
66
import time
77
import json
8+
import base64
89
import requests
910
import subprocess
1011

11-
from mytoncore.mytoncore import MyTonCore, Dec2HexAddr
12-
from mytoncore.tonblocksscanner import TonBlocksScanner
12+
from mytoncore.mytoncore import MyTonCore
13+
from mytoncore.utils import parse_db_stats
14+
from mytoninstaller.config import GetConfig
1315
from mypylib.mypylib import (
1416
b2mb,
1517
get_timestamp,
@@ -20,14 +22,15 @@
2022
thr_sleep,
2123
Dict
2224
)
25+
from mytoninstaller.node_args import get_node_args
2326

2427

2528
def Init(local):
2629
# Event reaction
2730
if ("-e" in sys.argv):
2831
x = sys.argv.index("-e")
29-
eventName = sys.argv[x+1]
30-
Event(local, eventName)
32+
event_name = sys.argv[x+1]
33+
Event(local, event_name)
3134
# end if
3235

3336
local.run()
@@ -46,11 +49,13 @@ def Init(local):
4649
# end define
4750

4851

49-
def Event(local, eventName):
50-
if eventName == "enableVC":
52+
def Event(local, event_name):
53+
if event_name == "enableVC":
5154
EnableVcEvent(local)
52-
elif eventName == "validator down":
55+
elif event_name == "validator down":
5356
ValidatorDownEvent(local)
57+
elif event_name == "enable_ton_storage_provider":
58+
enable_ton_storage_provider_event(local)
5459
local.exit()
5560
# end define
5661

@@ -78,6 +83,15 @@ def ValidatorDownEvent(local):
7883
# end define
7984

8085

86+
def enable_ton_storage_provider_event(local):
87+
config_path = local.db.ton_storage.provider.config_path
88+
config = GetConfig(path=config_path)
89+
key_bytes = base64.b64decode(config.ProviderKey)
90+
ton = MyTonCore(local)
91+
ton.import_wallet_with_version(key_bytes[:32], version="v3r2", wallet_name="provider_wallet_001")
92+
#end define
93+
94+
8195
def Elections(local, ton):
8296
use_pool = ton.using_pool()
8397
use_liquid_staking = ton.using_liquid_staking()
@@ -419,6 +433,90 @@ def GetValidatorProcessInfo():
419433
# end define
420434

421435

436+
def get_db_stats():
437+
result = {
438+
'rocksdb': {
439+
'ok': True,
440+
'message': '',
441+
'data': {}
442+
},
443+
'celldb': {
444+
'ok': True,
445+
'message': '',
446+
'data': {}
447+
},
448+
}
449+
rocksdb_stats_path = '/var/ton-work/db/db_stats.txt'
450+
celldb_stats_path = '/var/ton-work/db/celldb/db_stats.txt'
451+
if os.path.exists(rocksdb_stats_path):
452+
try:
453+
result['rocksdb']['data'] = parse_db_stats(rocksdb_stats_path)
454+
except Exception as e:
455+
result['rocksdb']['ok'] = False
456+
result['rocksdb']['message'] = f'failed to fetch db stats: {e}'
457+
else:
458+
result['rocksdb']['ok'] = False
459+
result['rocksdb']['message'] = 'db stats file is not exists'
460+
# end if
461+
462+
if os.path.exists(celldb_stats_path):
463+
try:
464+
result['celldb']['data'] = parse_db_stats(celldb_stats_path)
465+
except Exception as e:
466+
result['celldb']['ok'] = False
467+
result['celldb']['message'] = f'failed to fetch db stats: {e}'
468+
else:
469+
result['celldb']['ok'] = False
470+
result['celldb']['message'] = 'db stats file is not exists'
471+
# end if
472+
473+
return result
474+
# end define
475+
476+
477+
def get_cpu_name():
478+
with open('/proc/cpuinfo') as f:
479+
for line in f:
480+
if line.strip():
481+
if line.rstrip('\n').startswith('model name'):
482+
return line.rstrip('\n').split(':')[1].strip()
483+
return None
484+
485+
486+
def is_host_virtual():
487+
try:
488+
with open('/sys/class/dmi/id/product_name') as f:
489+
product_name = f.read().strip().lower()
490+
if 'virtual' in product_name or 'kvm' in product_name or 'qemu' in product_name or 'vmware' in product_name:
491+
return {'virtual': True, 'product_name': product_name}
492+
return {'virtual': False, 'product_name': product_name}
493+
except FileNotFoundError:
494+
return {'virtual': None, 'product_name': None}
495+
496+
497+
def do_beacon_ping(host, count, timeout):
498+
args = ['ping', '-c', str(count), '-W', str(timeout), host]
499+
process = subprocess.run(args, stdin=subprocess.PIPE,
500+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout)
501+
output = process.stdout.decode("utf-8")
502+
avg = output.split('\n')[-2].split('=')[1].split('/')[1]
503+
return float(avg)
504+
505+
506+
def get_pings_values():
507+
return {
508+
'beacon-eu-01.toncenter.com': do_beacon_ping('beacon-eu-01.toncenter.com', 5, 10),
509+
'beacon-apac-01.toncenter.com': do_beacon_ping('beacon-apac-01.toncenter.com', 5, 10)
510+
}
511+
512+
513+
def get_validator_disk_name():
514+
process = subprocess.run("df -h /var/ton-work/ | sed -n '2 p' | awk '{print $1}'", stdin=subprocess.PIPE,
515+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=3, shell=True)
516+
output = process.stdout.decode("utf-8")
517+
return output.strip()
518+
519+
422520
def Telemetry(local, ton):
423521
sendTelemetry = local.db.get("sendTelemetry")
424522
if sendTelemetry is not True:
@@ -442,6 +540,11 @@ def Telemetry(local, ton):
442540
data["swap"] = GetSwapInfo()
443541
data["uname"] = GetUname()
444542
data["vprocess"] = GetValidatorProcessInfo()
543+
data["dbStats"] = get_db_stats()
544+
data["nodeArgs"] = get_node_args()
545+
data["cpuInfo"] = {'cpuName': get_cpu_name(), 'virtual': is_host_virtual()}
546+
data["validatorDiskName"] = get_validator_disk_name()
547+
data["pings"] = get_pings_values()
445548
elections = local.try_function(ton.GetElectionEntries)
446549
complaints = local.try_function(ton.GetComplaints)
447550

0 commit comments

Comments
 (0)