naeural-client 2.6.37__py3-none-any.whl → 2.6.39__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- naeural_client/_ver.py +1 -1
- naeural_client/cli/oracles.py +1 -17
- naeural_client/logging/base_logger.py +18 -1
- naeural_client/utils/oracle_sync/{multiple_requests.py → oracle_tester.py} +129 -6
- {naeural_client-2.6.37.dist-info → naeural_client-2.6.39.dist-info}/METADATA +1 -1
- {naeural_client-2.6.37.dist-info → naeural_client-2.6.39.dist-info}/RECORD +9 -9
- {naeural_client-2.6.37.dist-info → naeural_client-2.6.39.dist-info}/WHEEL +0 -0
- {naeural_client-2.6.37.dist-info → naeural_client-2.6.39.dist-info}/entry_points.txt +0 -0
- {naeural_client-2.6.37.dist-info → naeural_client-2.6.39.dist-info}/licenses/LICENSE +0 -0
naeural_client/_ver.py
CHANGED
naeural_client/cli/oracles.py
CHANGED
@@ -95,26 +95,10 @@ TODO: (future)
|
|
95
95
|
- check ETH signature of the oracle data
|
96
96
|
|
97
97
|
"""
|
98
|
-
import requests
|
99
98
|
|
100
99
|
from naeural_client.utils.config import log_with_color
|
101
|
-
from naeural_client import
|
102
|
-
from naeural_client.bc import DefaultBlockEngine
|
103
|
-
from naeural_client.utils.oracle_sync.multiple_requests import oracle_tester_init, handle_command_results
|
100
|
+
from naeural_client.utils.oracle_sync.oracle_tester import oracle_tester_init, handle_command_results
|
104
101
|
|
105
|
-
"""
|
106
|
-
TODOs:
|
107
|
-
- test NEPCTL command in CLI too
|
108
|
-
- check ETH signature of the oracle data
|
109
|
-
"""
|
110
|
-
|
111
|
-
|
112
|
-
def _check_response(data):
|
113
|
-
res = True
|
114
|
-
log = Logger("NEPCTL", base_folder=".", app_folder="_local_cache", silent=True)
|
115
|
-
bc = DefaultBlockEngine(name='test', log=log)
|
116
|
-
print(bc.address)
|
117
|
-
return res
|
118
102
|
|
119
103
|
def get_availability(args):
|
120
104
|
"""
|
@@ -460,20 +460,37 @@ class BaseLogger(object):
|
|
460
460
|
import platform
|
461
461
|
import subprocess
|
462
462
|
import re
|
463
|
+
import multiprocessing
|
463
464
|
str_system = platform.system()
|
464
465
|
if str_system == "Windows":
|
465
466
|
self.processor_platform = platform.processor()
|
467
|
+
|
466
468
|
elif str_system == "Darwin":
|
467
469
|
os.environ['PATH'] = os.environ['PATH'] + os.pathsep + '/usr/sbin'
|
468
470
|
command ="sysctl -n machdep.cpu.brand_string"
|
469
471
|
self.processor_platform = subprocess.check_output(command, shell=True).strip().decode('utf-8')
|
472
|
+
|
470
473
|
elif str_system == "Linux":
|
471
474
|
command = "cat /proc/cpuinfo"
|
472
475
|
all_info = subprocess.check_output(command, shell=True).decode().strip()
|
476
|
+
proc_platform = None
|
473
477
|
for line in all_info.split("\n"):
|
474
478
|
if "model name" in line:
|
475
|
-
|
479
|
+
proc_platform = re.sub( ".*model name.*:", "", line,1)
|
476
480
|
break
|
481
|
+
if proc_platform is None:
|
482
|
+
cores = multiprocessing.cpu_count()
|
483
|
+
proc_platform = "Unknown"
|
484
|
+
try:
|
485
|
+
lscpu_out = subprocess.check_output("lscpu", shell=True).decode().strip()
|
486
|
+
match_vendor = re.search(r"Vendor ID:\s+(.*)", lscpu_out)
|
487
|
+
if match_vendor:
|
488
|
+
proc_platform = match_vendor.group(1)
|
489
|
+
except:
|
490
|
+
pass
|
491
|
+
proc_platform = f"{proc_platform} {cores} cores"
|
492
|
+
#endif no model name
|
493
|
+
self.processor_platform = proc_platform
|
477
494
|
return
|
478
495
|
|
479
496
|
def get_processor_platform(self):
|
@@ -10,7 +10,8 @@ from collections import defaultdict
|
|
10
10
|
|
11
11
|
from naeural_client import Logger
|
12
12
|
from naeural_client.bc import DefaultBlockEngine
|
13
|
-
from naeural_client.utils.config import log_with_color
|
13
|
+
from naeural_client.utils.config import log_with_color, get_user_folder
|
14
|
+
|
14
15
|
|
15
16
|
|
16
17
|
class OracleTesterConstants:
|
@@ -23,6 +24,7 @@ class OracleTesterConstants:
|
|
23
24
|
MAX_REQUEST_ROUNDS = 10
|
24
25
|
FREQUENCY = "frequency"
|
25
26
|
ORACLE_DATA = "oracle_data"
|
27
|
+
DEFAULT_MIN_CERTAINTY_PRC = 0.98
|
26
28
|
|
27
29
|
|
28
30
|
ct = OracleTesterConstants
|
@@ -115,8 +117,10 @@ class OracleTester:
|
|
115
117
|
"""
|
116
118
|
epoch_ids = result.get("epochs")
|
117
119
|
epoch_vals = result.get("epochs_vals")
|
118
|
-
|
119
|
-
|
120
|
+
manager_data = result.get("oracle", {}).get("manager", {})
|
121
|
+
dict_certainty = manager_data.get("certainty", {})
|
122
|
+
is_valid = manager_data.get("valid", False)
|
123
|
+
min_certainty_prc = manager_data.get("supervisor_min_avail_prc", ct.DEFAULT_MIN_CERTAINTY_PRC)
|
120
124
|
|
121
125
|
current_epochs, current_avails, current_cert = [], [], []
|
122
126
|
for epoch_id, epoch_val in zip(epoch_ids, epoch_vals):
|
@@ -124,7 +128,7 @@ class OracleTester:
|
|
124
128
|
current_avails.append(epoch_val)
|
125
129
|
current_cert.append(dict_certainty.get(str(epoch_id), 0))
|
126
130
|
# endfor epochs
|
127
|
-
return current_epochs, current_avails, current_cert, is_valid
|
131
|
+
return current_epochs, current_avails, current_cert, is_valid, min_certainty_prc
|
128
132
|
|
129
133
|
def handle_server_data(
|
130
134
|
self, oracle_stats_dict: dict,
|
@@ -156,11 +160,13 @@ class OracleTester:
|
|
156
160
|
}
|
157
161
|
# endif first time for this sender
|
158
162
|
current_stats = oracle_stats_dict[sender]
|
159
|
-
|
163
|
+
# TODO: maybe automate this (have only the list of keys to go through).
|
164
|
+
current_epochs, current_avails, current_certs, is_valid, min_certainty_prc = self.compute_epochs_availability_and_certainty(result)
|
160
165
|
stats_epochs = current_stats.get("epochs", None)
|
161
166
|
stats_avails = current_stats.get("avails", None)
|
162
167
|
stats_certs = current_stats.get("certs", None)
|
163
168
|
stats_is_valid = current_stats.get("is_valid", None)
|
169
|
+
stats_min_certainty_prc = current_stats.get("min_certainty_prc", None)
|
164
170
|
mismatches = []
|
165
171
|
if stats_epochs is not None and current_epochs != stats_epochs:
|
166
172
|
mismatches.append(f"epochs: {current_epochs} != {stats_epochs}")
|
@@ -174,6 +180,9 @@ class OracleTester:
|
|
174
180
|
if stats_is_valid is not None and is_valid != stats_is_valid:
|
175
181
|
mismatches.append(f"validity: {is_valid} != {stats_is_valid}")
|
176
182
|
# endif check for mismatch
|
183
|
+
if stats_min_certainty_prc is not None and min_certainty_prc != stats_min_certainty_prc:
|
184
|
+
mismatches.append(f"min_certainty_prc: {min_certainty_prc} != {stats_min_certainty_prc}")
|
185
|
+
# endif check for mismatch
|
177
186
|
|
178
187
|
if len(mismatches) > 0:
|
179
188
|
current_stats["errors"].append(f"Round {self.request_rounds}: {', '.join(mismatches)}")
|
@@ -187,6 +196,8 @@ class OracleTester:
|
|
187
196
|
current_stats["certs"] = current_certs
|
188
197
|
if stats_is_valid is None:
|
189
198
|
current_stats["is_valid"] = is_valid
|
199
|
+
if stats_min_certainty_prc is None:
|
200
|
+
current_stats["min_certainty_prc"] = min_certainty_prc
|
190
201
|
# endif valid data received
|
191
202
|
return
|
192
203
|
|
@@ -298,6 +309,78 @@ class OracleTester:
|
|
298
309
|
self.P(f'Finished gathering data for {len(nodes)} nodes and {self.max_request_rounds}.')
|
299
310
|
return responses, stats_dict
|
300
311
|
|
312
|
+
def gather_and_compare(self, nodes, request_kwargs=None, debug=False, rounds=None):
|
313
|
+
"""
|
314
|
+
Gather data from the oracle server for the given nodes and compare the results between oracles.
|
315
|
+
|
316
|
+
Parameters
|
317
|
+
----------
|
318
|
+
nodes : list[dict] or list[str]
|
319
|
+
The list of nodes for which to gather data. Each node can be a dictionary containing the
|
320
|
+
address, eth_address, and alias of the node or a string containing the eth_address of the node.
|
321
|
+
Either way, the eth_address is required.
|
322
|
+
request_kwargs : dict
|
323
|
+
The request kwargs to be used for the request. Default None.
|
324
|
+
debug : bool
|
325
|
+
Whether to enable debug mode or not. If enabled the function will exit after one request round.
|
326
|
+
|
327
|
+
Returns
|
328
|
+
-------
|
329
|
+
tuple
|
330
|
+
A tuple containing the responses and the stats dictionary.
|
331
|
+
"""
|
332
|
+
responses, stats_dict = self.gather(
|
333
|
+
nodes=nodes,
|
334
|
+
request_kwargs=request_kwargs,
|
335
|
+
debug=debug,
|
336
|
+
rounds=rounds
|
337
|
+
)
|
338
|
+
# Statistics for each node of each epoch
|
339
|
+
epochs_nodes_stats = {}
|
340
|
+
# Statistics for each epoch of each node
|
341
|
+
nodes_epochs_stats = {}
|
342
|
+
for node_eth_addr, node_data in stats_dict.items():
|
343
|
+
oracle_data = node_data.get(ct.ORACLE_DATA, {})
|
344
|
+
errors = oracle_data.get("errors", [])
|
345
|
+
if len(errors) > 0:
|
346
|
+
self.P(f'#######################{node_eth_addr} errors########################')
|
347
|
+
self.P(f"Errors for {node_eth_addr}:\n" + '\n'.join(errors), color='r')
|
348
|
+
self.P(f'#######################{node_eth_addr} errors########################')
|
349
|
+
# endif
|
350
|
+
|
351
|
+
if node_eth_addr not in nodes_epochs_stats:
|
352
|
+
# This check should not be necessary, but just in case
|
353
|
+
nodes_epochs_stats[node_eth_addr] = {}
|
354
|
+
# endif first time for this node
|
355
|
+
|
356
|
+
epochs_stats = nodes_epochs_stats[node_eth_addr]
|
357
|
+
epochs = oracle_data.get("epochs", []),
|
358
|
+
avails = oracle_data.get("avails", []),
|
359
|
+
certs = oracle_data.get("certs", [])
|
360
|
+
min_certainty_prc = oracle_data.get("stats_min_certainty_prc", ct.DEFAULT_MIN_CERTAINTY_PRC)
|
361
|
+
for epoch, avail, cert in zip(epochs, avails, certs):
|
362
|
+
if epoch not in epochs_nodes_stats:
|
363
|
+
epochs_nodes_stats[epoch] = {}
|
364
|
+
# endif epoch not in stats
|
365
|
+
if epoch not in epochs_stats:
|
366
|
+
epochs_stats[epoch] = {}
|
367
|
+
# endif epoch not in stats
|
368
|
+
node_stats = epochs_nodes_stats[epoch]
|
369
|
+
|
370
|
+
if cert >= min_certainty_prc:
|
371
|
+
if avail not in epochs_stats[epoch]:
|
372
|
+
epochs_stats[epoch][avail] = set()
|
373
|
+
if avail not in node_stats:
|
374
|
+
node_stats[avail] = set()
|
375
|
+
# endif first time encountering this availability
|
376
|
+
epochs_stats[epoch][avail].add(node_eth_addr)
|
377
|
+
node_stats[avail].add(node_eth_addr)
|
378
|
+
# endif valid data
|
379
|
+
# endfor each epoch
|
380
|
+
|
381
|
+
|
382
|
+
return responses, stats_dict
|
383
|
+
|
301
384
|
def get_current_epoch(self):
|
302
385
|
epoch_url = self.BASE_URL + self.CURRENT_EPOCH_ENDPOINT
|
303
386
|
response = self.make_request(epoch_url)
|
@@ -490,8 +573,14 @@ def handle_command_results(res):
|
|
490
573
|
return
|
491
574
|
|
492
575
|
def oracle_tester_init(silent=True, **kwargs):
|
493
|
-
log = Logger(
|
576
|
+
log = Logger(
|
577
|
+
"R1CTL",
|
578
|
+
base_folder=get_user_folder(),
|
579
|
+
app_folder="_local_cache",
|
580
|
+
silent=silent
|
581
|
+
)
|
494
582
|
bc = DefaultBlockEngine(name='R1CTL', log=log)
|
583
|
+
|
495
584
|
tester = OracleTester(
|
496
585
|
bce=bc,
|
497
586
|
log=log,
|
@@ -521,6 +610,40 @@ def test_commands():
|
|
521
610
|
handle_command_results(res)
|
522
611
|
return
|
523
612
|
|
613
|
+
def oracle_check(N=10):
|
614
|
+
import random
|
615
|
+
random.seed(42)
|
616
|
+
|
617
|
+
tester = oracle_tester_init(
|
618
|
+
silent=True,
|
619
|
+
interval_seconds=0.2,
|
620
|
+
)
|
621
|
+
current_epoch = tester.get_current_epoch()
|
622
|
+
if current_epoch is None:
|
623
|
+
current_epoch = 100
|
624
|
+
nodes = tester.get_active_nodes()
|
625
|
+
rounds = 5
|
626
|
+
max_epochs = 10
|
627
|
+
max_nodes = 5
|
628
|
+
|
629
|
+
nodes = nodes[:max_nodes]
|
630
|
+
for i in range(N):
|
631
|
+
start = random.randint(1, current_epoch - 1)
|
632
|
+
end = random.randint(start, current_epoch - 1)
|
633
|
+
end = min(end, start + max_epochs - 1)
|
634
|
+
|
635
|
+
tester.P(f'Test {i + 1}/{N}: Epochs {start} to {end} with {rounds} rounds:', show=True)
|
636
|
+
tester.gather_and_compare(
|
637
|
+
nodes=nodes,
|
638
|
+
request_kwargs={
|
639
|
+
"start_epoch": start,
|
640
|
+
"end_epoch": end
|
641
|
+
},
|
642
|
+
)
|
643
|
+
tester.P(f'Finished test {i + 1}/{N}', show=True)
|
644
|
+
# endfor each test
|
645
|
+
return
|
646
|
+
|
524
647
|
def oracle_test(N=10):
|
525
648
|
import random
|
526
649
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: naeural_client
|
3
|
-
Version: 2.6.
|
3
|
+
Version: 2.6.39
|
4
4
|
Summary: `naeural_client` is the Python SDK required for client app development for the Naeural Edge Protocol Edge Protocol framework
|
5
5
|
Project-URL: Homepage, https://github.com/NaeuralEdgeProtocol/naeural_client
|
6
6
|
Project-URL: Bug Tracker, https://github.com/NaeuralEdgeProtocol/naeural_client/issues
|
@@ -1,5 +1,5 @@
|
|
1
1
|
naeural_client/__init__.py,sha256=YimqgDbjLuywsf8zCWE0EaUXH4MBUrqLxt0TDV558hQ,632
|
2
|
-
naeural_client/_ver.py,sha256=
|
2
|
+
naeural_client/_ver.py,sha256=LKmpmF9zipVxTAWBLJnSORTzUky-UsiIPtU_RbkZbB8,331
|
3
3
|
naeural_client/base_decentra_object.py,sha256=C4iwZTkhKNBS4VHlJs5DfElRYLo4Q9l1V1DNVSk1fyQ,4412
|
4
4
|
naeural_client/plugins_manager_mixin.py,sha256=X1JdGLDz0gN1rPnTN_5mJXR8JmqoBFQISJXmPR9yvCo,11106
|
5
5
|
naeural_client/base/__init__.py,sha256=hACh83_cIv7-PwYMM3bQm2IBmNqiHw-3PAfDfAEKz9A,259
|
@@ -23,7 +23,7 @@ naeural_client/cli/README.md,sha256=WPdI_EjzAbUW1aPyj1sSR8rLydcJKZtoiaEtklQrjHo,
|
|
23
23
|
naeural_client/cli/cli.py,sha256=EC7-ehOMQJ_Dq7R9TTrajpvQWwdalAOgb1JAeBGHF50,3830
|
24
24
|
naeural_client/cli/cli_commands.py,sha256=Gfims_TqaBi2QWM-6yxd_B_CETF8mmt7oEDPTg59lcI,2821
|
25
25
|
naeural_client/cli/nodes.py,sha256=QXSniYy3Phr6buoVV-HUDRYuF5YQDUgf6nT6EzDyMJw,4909
|
26
|
-
naeural_client/cli/oracles.py,sha256=
|
26
|
+
naeural_client/cli/oracles.py,sha256=Y_PzHshfSERS_Utjjtw5d_BsQRdGr6P4L6uW8yTdA0M,4809
|
27
27
|
naeural_client/code_cheker/__init__.py,sha256=pwkdeZGVL16ZA4Qf2mRahEhoOvKhL7FyuQbMFLr1E5M,33
|
28
28
|
naeural_client/code_cheker/base.py,sha256=lT5DRIFO5rqzsMNCmdMRfkAeevmezozehyfgmhnKpuI,19074
|
29
29
|
naeural_client/code_cheker/checker.py,sha256=QWupeM7ToancVIq1tRUxRNUrI8B5l5eoY0kDU4-O5aE,7365
|
@@ -58,7 +58,7 @@ naeural_client/io_formatter/default/a_dummy.py,sha256=qr9eUizQ-NN5jdXVzkaZKMaf9K
|
|
58
58
|
naeural_client/io_formatter/default/aixp1.py,sha256=MX0TeUR4APA-qN3vUC6uzcz8Pssz5lgrQWo7td5Ri1A,3052
|
59
59
|
naeural_client/io_formatter/default/default.py,sha256=gEy78cP2D5s0y8vQh4aHuxqz7D10gGfuiKF311QhrpE,494
|
60
60
|
naeural_client/logging/__init__.py,sha256=b79X45VC6c37u32flKB2GAK9f-RR0ocwP0JDCy0t7QQ,33
|
61
|
-
naeural_client/logging/base_logger.py,sha256=
|
61
|
+
naeural_client/logging/base_logger.py,sha256=sTdY0IudHyJKluKkJexyR4ZCZvO1XVKwKMjc1LeOL5E,67694
|
62
62
|
naeural_client/logging/small_logger.py,sha256=m12hCb_H4XifJYYfgCAOUDkcXm-h4pSODnFf277OFVI,2937
|
63
63
|
naeural_client/logging/logger_mixins/__init__.py,sha256=yQO7umlRvz63FeWpi-F9GRmC_MOHcNW6R6pwvZZBy3A,600
|
64
64
|
naeural_client/logging/logger_mixins/class_instance_mixin.py,sha256=xUXE2VZgmrlrSrvw0f6GF1jlTnVLeVkIiG0bhlBfq3o,2741
|
@@ -82,9 +82,9 @@ naeural_client/utils/__init__.py,sha256=mAnke3-MeRzz3nhQvhuHqLnpaaCSmDxicd7Ck9uw
|
|
82
82
|
naeural_client/utils/comm_utils.py,sha256=4cS9llRr_pK_3rNgDcRMCQwYPO0kcNU7AdWy_LtMyCY,1072
|
83
83
|
naeural_client/utils/config.py,sha256=Ub5sw3NG6wskAF5C4s0WU0rzXHVLy70ZTRU0W8HUGTM,6403
|
84
84
|
naeural_client/utils/dotenv.py,sha256=_AgSo35n7EnQv5yDyu7C7i0kHragLJoCGydHjvOkrYY,2008
|
85
|
-
naeural_client/utils/oracle_sync/
|
86
|
-
naeural_client-2.6.
|
87
|
-
naeural_client-2.6.
|
88
|
-
naeural_client-2.6.
|
89
|
-
naeural_client-2.6.
|
90
|
-
naeural_client-2.6.
|
85
|
+
naeural_client/utils/oracle_sync/oracle_tester.py,sha256=wBetjbJ8Z6VjTn0y7aqxL59Z9Qy1sukJ4bGlykNf0vA,25307
|
86
|
+
naeural_client-2.6.39.dist-info/METADATA,sha256=CS5uWfA_sKzkNFWHmh4N-iv22ym-wyL5NiEZVez-6Ys,12354
|
87
|
+
naeural_client-2.6.39.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
88
|
+
naeural_client-2.6.39.dist-info/entry_points.txt,sha256=CTua17GUrRa4aXeafezGC9TiWKGKQzwTjQmB2jyj22g,91
|
89
|
+
naeural_client-2.6.39.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
|
90
|
+
naeural_client-2.6.39.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|