nexaroa 0.0.111__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.
- neuroshard/__init__.py +93 -0
- neuroshard/__main__.py +4 -0
- neuroshard/cli.py +466 -0
- neuroshard/core/__init__.py +92 -0
- neuroshard/core/consensus/verifier.py +252 -0
- neuroshard/core/crypto/__init__.py +20 -0
- neuroshard/core/crypto/ecdsa.py +392 -0
- neuroshard/core/economics/__init__.py +52 -0
- neuroshard/core/economics/constants.py +387 -0
- neuroshard/core/economics/ledger.py +2111 -0
- neuroshard/core/economics/market.py +975 -0
- neuroshard/core/economics/wallet.py +168 -0
- neuroshard/core/governance/__init__.py +74 -0
- neuroshard/core/governance/proposal.py +561 -0
- neuroshard/core/governance/registry.py +545 -0
- neuroshard/core/governance/versioning.py +332 -0
- neuroshard/core/governance/voting.py +453 -0
- neuroshard/core/model/__init__.py +30 -0
- neuroshard/core/model/dynamic.py +4186 -0
- neuroshard/core/model/llm.py +905 -0
- neuroshard/core/model/registry.py +164 -0
- neuroshard/core/model/scaler.py +387 -0
- neuroshard/core/model/tokenizer.py +568 -0
- neuroshard/core/network/__init__.py +56 -0
- neuroshard/core/network/connection_pool.py +72 -0
- neuroshard/core/network/dht.py +130 -0
- neuroshard/core/network/dht_plan.py +55 -0
- neuroshard/core/network/dht_proof_store.py +516 -0
- neuroshard/core/network/dht_protocol.py +261 -0
- neuroshard/core/network/dht_service.py +506 -0
- neuroshard/core/network/encrypted_channel.py +141 -0
- neuroshard/core/network/nat.py +201 -0
- neuroshard/core/network/nat_traversal.py +695 -0
- neuroshard/core/network/p2p.py +929 -0
- neuroshard/core/network/p2p_data.py +150 -0
- neuroshard/core/swarm/__init__.py +106 -0
- neuroshard/core/swarm/aggregation.py +729 -0
- neuroshard/core/swarm/buffers.py +643 -0
- neuroshard/core/swarm/checkpoint.py +709 -0
- neuroshard/core/swarm/compute.py +624 -0
- neuroshard/core/swarm/diloco.py +844 -0
- neuroshard/core/swarm/factory.py +1288 -0
- neuroshard/core/swarm/heartbeat.py +669 -0
- neuroshard/core/swarm/logger.py +487 -0
- neuroshard/core/swarm/router.py +658 -0
- neuroshard/core/swarm/service.py +640 -0
- neuroshard/core/training/__init__.py +29 -0
- neuroshard/core/training/checkpoint.py +600 -0
- neuroshard/core/training/distributed.py +1602 -0
- neuroshard/core/training/global_tracker.py +617 -0
- neuroshard/core/training/production.py +276 -0
- neuroshard/governance_cli.py +729 -0
- neuroshard/grpc_server.py +895 -0
- neuroshard/runner.py +3223 -0
- neuroshard/sdk/__init__.py +92 -0
- neuroshard/sdk/client.py +990 -0
- neuroshard/sdk/errors.py +101 -0
- neuroshard/sdk/types.py +282 -0
- neuroshard/tracker/__init__.py +0 -0
- neuroshard/tracker/server.py +864 -0
- neuroshard/ui/__init__.py +0 -0
- neuroshard/ui/app.py +102 -0
- neuroshard/ui/templates/index.html +1052 -0
- neuroshard/utils/__init__.py +0 -0
- neuroshard/utils/autostart.py +81 -0
- neuroshard/utils/hardware.py +121 -0
- neuroshard/utils/serialization.py +90 -0
- neuroshard/version.py +1 -0
- nexaroa-0.0.111.dist-info/METADATA +283 -0
- nexaroa-0.0.111.dist-info/RECORD +78 -0
- nexaroa-0.0.111.dist-info/WHEEL +5 -0
- nexaroa-0.0.111.dist-info/entry_points.txt +4 -0
- nexaroa-0.0.111.dist-info/licenses/LICENSE +190 -0
- nexaroa-0.0.111.dist-info/top_level.txt +2 -0
- protos/__init__.py +0 -0
- protos/neuroshard.proto +651 -0
- protos/neuroshard_pb2.py +160 -0
- protos/neuroshard_pb2_grpc.py +1298 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
import time
|
|
3
|
+
import bisect
|
|
4
|
+
from typing import List, Tuple, Dict
|
|
5
|
+
|
|
6
|
+
K_BUCKET_SIZE = 20
|
|
7
|
+
ID_BITS = 160
|
|
8
|
+
|
|
9
|
+
class Node:
|
|
10
|
+
def __init__(self, node_id: int, ip: str, port: int):
|
|
11
|
+
self.id = node_id
|
|
12
|
+
self.ip = ip
|
|
13
|
+
self.port = port
|
|
14
|
+
self.last_seen = time.time()
|
|
15
|
+
|
|
16
|
+
def __eq__(self, other):
|
|
17
|
+
return self.id == other.id
|
|
18
|
+
|
|
19
|
+
def __repr__(self):
|
|
20
|
+
return f"<Node {hex(self.id)[:6]}... {self.ip}:{self.port}>"
|
|
21
|
+
|
|
22
|
+
class KBucket:
|
|
23
|
+
def __init__(self, lower: int, upper: int):
|
|
24
|
+
self.range = (lower, upper)
|
|
25
|
+
self.nodes: List[Node] = []
|
|
26
|
+
self.lock = threading.Lock()
|
|
27
|
+
|
|
28
|
+
def add_node(self, node: Node) -> bool:
|
|
29
|
+
"""
|
|
30
|
+
Add node to bucket.
|
|
31
|
+
Returns True if added/updated, False if bucket full and needs splitting (not handled here).
|
|
32
|
+
"""
|
|
33
|
+
with self.lock:
|
|
34
|
+
# Check if node exists
|
|
35
|
+
for i, n in enumerate(self.nodes):
|
|
36
|
+
if n.id == node.id:
|
|
37
|
+
# Move to tail (most recently seen)
|
|
38
|
+
self.nodes.pop(i)
|
|
39
|
+
self.nodes.append(node)
|
|
40
|
+
return True
|
|
41
|
+
|
|
42
|
+
if len(self.nodes) < K_BUCKET_SIZE:
|
|
43
|
+
self.nodes.append(node)
|
|
44
|
+
return True
|
|
45
|
+
else:
|
|
46
|
+
# Bucket full
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
def get_nodes(self) -> List[Node]:
|
|
50
|
+
with self.lock:
|
|
51
|
+
return list(self.nodes)
|
|
52
|
+
|
|
53
|
+
class RoutingTable:
|
|
54
|
+
def __init__(self, local_node: Node):
|
|
55
|
+
self.local_node = local_node
|
|
56
|
+
self.buckets: List[KBucket] = [KBucket(0, 2**ID_BITS)]
|
|
57
|
+
self.lock = threading.Lock()
|
|
58
|
+
|
|
59
|
+
def _bucket_index(self, node_id: int) -> int:
|
|
60
|
+
# Linear scan for simplicity, can be optimized with Trie or bit logs
|
|
61
|
+
for i, b in enumerate(self.buckets):
|
|
62
|
+
if b.range[0] <= node_id < b.range[1]:
|
|
63
|
+
return i
|
|
64
|
+
return -1
|
|
65
|
+
|
|
66
|
+
def add_contact(self, node: Node):
|
|
67
|
+
if node.id == self.local_node.id:
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
with self.lock:
|
|
71
|
+
# Iterative attempt to add node, handling splits
|
|
72
|
+
while True:
|
|
73
|
+
index = self._bucket_index(node.id)
|
|
74
|
+
if index == -1: # Should not happen
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
bucket = self.buckets[index]
|
|
78
|
+
|
|
79
|
+
if bucket.add_node(node):
|
|
80
|
+
return # Success
|
|
81
|
+
|
|
82
|
+
# Bucket is full, try to split
|
|
83
|
+
# Only split if local node falls in this bucket range OR (relaxed) depth is small
|
|
84
|
+
can_split = (bucket.range[0] <= self.local_node.id < bucket.range[1]) or (len(self.buckets) < ID_BITS)
|
|
85
|
+
|
|
86
|
+
if can_split:
|
|
87
|
+
self._split_bucket(index)
|
|
88
|
+
# Loop continues to try adding again in the new bucket structure
|
|
89
|
+
else:
|
|
90
|
+
# Cannot split, drop node (or ping oldest in full impl)
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
def _split_bucket(self, index: int):
|
|
94
|
+
# Assumes lock is held by caller
|
|
95
|
+
bucket = self.buckets[index]
|
|
96
|
+
lower, upper = bucket.range
|
|
97
|
+
mid = lower + (upper - lower) // 2
|
|
98
|
+
|
|
99
|
+
left = KBucket(lower, mid)
|
|
100
|
+
right = KBucket(mid, upper)
|
|
101
|
+
|
|
102
|
+
# Redistribute nodes
|
|
103
|
+
for n in bucket.nodes:
|
|
104
|
+
if n.id < mid:
|
|
105
|
+
left.add_node(n)
|
|
106
|
+
else:
|
|
107
|
+
right.add_node(n)
|
|
108
|
+
|
|
109
|
+
# Replace old bucket with the two new ones
|
|
110
|
+
self.buckets[index] = left
|
|
111
|
+
self.buckets.insert(index + 1, right)
|
|
112
|
+
|
|
113
|
+
def get_all_nodes(self) -> List[Node]:
|
|
114
|
+
"""Return all known nodes in the routing table."""
|
|
115
|
+
with self.lock:
|
|
116
|
+
all_nodes = []
|
|
117
|
+
for b in self.buckets:
|
|
118
|
+
all_nodes.extend(b.nodes)
|
|
119
|
+
return all_nodes
|
|
120
|
+
|
|
121
|
+
def find_closest(self, target_id: int, k: int = K_BUCKET_SIZE) -> List[Node]:
|
|
122
|
+
"""Find k nodes closest to target_id (XOR metric)"""
|
|
123
|
+
with self.lock:
|
|
124
|
+
all_nodes = []
|
|
125
|
+
for b in self.buckets:
|
|
126
|
+
all_nodes.extend(b.nodes)
|
|
127
|
+
|
|
128
|
+
# Sort by XOR distance
|
|
129
|
+
all_nodes.sort(key=lambda n: n.id ^ target_id)
|
|
130
|
+
return all_nodes[:k]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
NeuroShard Kademlia DHT Implementation Plan
|
|
3
|
+
|
|
4
|
+
1. Node ID & Distance Metric
|
|
5
|
+
- SHA-1 or SHA-256 hash of (IP + Port + Random) -> 160-bit ID.
|
|
6
|
+
- Distance: XOR metric.
|
|
7
|
+
|
|
8
|
+
2. Routing Table (K-Buckets)
|
|
9
|
+
- List of buckets where index i contains nodes with distance 2^i to 2^(i+1).
|
|
10
|
+
- K=20 (Standard Kademlia parameter).
|
|
11
|
+
- Replacement cache for unresponsive nodes.
|
|
12
|
+
|
|
13
|
+
3. Protocol Messages (RPCs)
|
|
14
|
+
- PING: Check liveness.
|
|
15
|
+
- STORE(key, value): Store peer info or shard location.
|
|
16
|
+
- FIND_NODE(target_id): Returns k closest nodes to target.
|
|
17
|
+
- FIND_VALUE(key): Returns value if present, else k closest nodes.
|
|
18
|
+
|
|
19
|
+
4. Storage
|
|
20
|
+
- Values are Peer Metadata: {ip, port, shard_range, last_seen}.
|
|
21
|
+
- Keys: Hash of the shard_range (e.g., hash("0-4")) or Node ID.
|
|
22
|
+
|
|
23
|
+
5. Bootstrapping
|
|
24
|
+
- Join network by contacting any known node (can fallback to Tracker temporarily).
|
|
25
|
+
- Perform node lookup for self ID to populate buckets.
|
|
26
|
+
|
|
27
|
+
6. Integration
|
|
28
|
+
- P2PManager will query DHT for "Layer X" peers instead of asking Tracker.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
import hashlib
|
|
32
|
+
import time
|
|
33
|
+
from typing import List, Optional
|
|
34
|
+
|
|
35
|
+
K_BUCKET_SIZE = 20
|
|
36
|
+
ID_LENGTH_BITS = 160
|
|
37
|
+
|
|
38
|
+
def generate_id(data: str) -> int:
|
|
39
|
+
"""Generate 160-bit ID."""
|
|
40
|
+
return int(hashlib.sha1(data.encode()).hexdigest(), 16)
|
|
41
|
+
|
|
42
|
+
class DHTNode:
|
|
43
|
+
def __init__(self, ip: str, port: int, id: Optional[int] = None):
|
|
44
|
+
self.ip = ip
|
|
45
|
+
self.port = port
|
|
46
|
+
self.id = id if id else generate_id(f"{ip}:{port}:{time.time()}")
|
|
47
|
+
self.last_seen = time.time()
|
|
48
|
+
|
|
49
|
+
def distance_to(self, other_id: int) -> int:
|
|
50
|
+
return self.id ^ other_id
|
|
51
|
+
|
|
52
|
+
def __repr__(self):
|
|
53
|
+
return f"<DHTNode {self.id} {self.ip}:{self.port}>"
|
|
54
|
+
|
|
55
|
+
|