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.
Files changed (78) hide show
  1. neuroshard/__init__.py +93 -0
  2. neuroshard/__main__.py +4 -0
  3. neuroshard/cli.py +466 -0
  4. neuroshard/core/__init__.py +92 -0
  5. neuroshard/core/consensus/verifier.py +252 -0
  6. neuroshard/core/crypto/__init__.py +20 -0
  7. neuroshard/core/crypto/ecdsa.py +392 -0
  8. neuroshard/core/economics/__init__.py +52 -0
  9. neuroshard/core/economics/constants.py +387 -0
  10. neuroshard/core/economics/ledger.py +2111 -0
  11. neuroshard/core/economics/market.py +975 -0
  12. neuroshard/core/economics/wallet.py +168 -0
  13. neuroshard/core/governance/__init__.py +74 -0
  14. neuroshard/core/governance/proposal.py +561 -0
  15. neuroshard/core/governance/registry.py +545 -0
  16. neuroshard/core/governance/versioning.py +332 -0
  17. neuroshard/core/governance/voting.py +453 -0
  18. neuroshard/core/model/__init__.py +30 -0
  19. neuroshard/core/model/dynamic.py +4186 -0
  20. neuroshard/core/model/llm.py +905 -0
  21. neuroshard/core/model/registry.py +164 -0
  22. neuroshard/core/model/scaler.py +387 -0
  23. neuroshard/core/model/tokenizer.py +568 -0
  24. neuroshard/core/network/__init__.py +56 -0
  25. neuroshard/core/network/connection_pool.py +72 -0
  26. neuroshard/core/network/dht.py +130 -0
  27. neuroshard/core/network/dht_plan.py +55 -0
  28. neuroshard/core/network/dht_proof_store.py +516 -0
  29. neuroshard/core/network/dht_protocol.py +261 -0
  30. neuroshard/core/network/dht_service.py +506 -0
  31. neuroshard/core/network/encrypted_channel.py +141 -0
  32. neuroshard/core/network/nat.py +201 -0
  33. neuroshard/core/network/nat_traversal.py +695 -0
  34. neuroshard/core/network/p2p.py +929 -0
  35. neuroshard/core/network/p2p_data.py +150 -0
  36. neuroshard/core/swarm/__init__.py +106 -0
  37. neuroshard/core/swarm/aggregation.py +729 -0
  38. neuroshard/core/swarm/buffers.py +643 -0
  39. neuroshard/core/swarm/checkpoint.py +709 -0
  40. neuroshard/core/swarm/compute.py +624 -0
  41. neuroshard/core/swarm/diloco.py +844 -0
  42. neuroshard/core/swarm/factory.py +1288 -0
  43. neuroshard/core/swarm/heartbeat.py +669 -0
  44. neuroshard/core/swarm/logger.py +487 -0
  45. neuroshard/core/swarm/router.py +658 -0
  46. neuroshard/core/swarm/service.py +640 -0
  47. neuroshard/core/training/__init__.py +29 -0
  48. neuroshard/core/training/checkpoint.py +600 -0
  49. neuroshard/core/training/distributed.py +1602 -0
  50. neuroshard/core/training/global_tracker.py +617 -0
  51. neuroshard/core/training/production.py +276 -0
  52. neuroshard/governance_cli.py +729 -0
  53. neuroshard/grpc_server.py +895 -0
  54. neuroshard/runner.py +3223 -0
  55. neuroshard/sdk/__init__.py +92 -0
  56. neuroshard/sdk/client.py +990 -0
  57. neuroshard/sdk/errors.py +101 -0
  58. neuroshard/sdk/types.py +282 -0
  59. neuroshard/tracker/__init__.py +0 -0
  60. neuroshard/tracker/server.py +864 -0
  61. neuroshard/ui/__init__.py +0 -0
  62. neuroshard/ui/app.py +102 -0
  63. neuroshard/ui/templates/index.html +1052 -0
  64. neuroshard/utils/__init__.py +0 -0
  65. neuroshard/utils/autostart.py +81 -0
  66. neuroshard/utils/hardware.py +121 -0
  67. neuroshard/utils/serialization.py +90 -0
  68. neuroshard/version.py +1 -0
  69. nexaroa-0.0.111.dist-info/METADATA +283 -0
  70. nexaroa-0.0.111.dist-info/RECORD +78 -0
  71. nexaroa-0.0.111.dist-info/WHEEL +5 -0
  72. nexaroa-0.0.111.dist-info/entry_points.txt +4 -0
  73. nexaroa-0.0.111.dist-info/licenses/LICENSE +190 -0
  74. nexaroa-0.0.111.dist-info/top_level.txt +2 -0
  75. protos/__init__.py +0 -0
  76. protos/neuroshard.proto +651 -0
  77. protos/neuroshard_pb2.py +160 -0
  78. protos/neuroshard_pb2_grpc.py +1298 -0
@@ -0,0 +1,453 @@
1
+ """
2
+ NEP Voting - Stake-Weighted Governance
3
+
4
+ Voting power is proportional to staked NEURO. This ensures that
5
+ participants with skin in the game make decisions about protocol changes.
6
+
7
+ Voting Rules:
8
+ - 1 NEURO staked = 1 vote
9
+ - Voting period: 7 days (configurable per NEP)
10
+ - Approval threshold: 66% of votes (stake-weighted)
11
+ - Quorum: 20% of total staked NEURO must vote
12
+ """
13
+
14
+ import sqlite3
15
+ import time
16
+ import hashlib
17
+ import json
18
+ import logging
19
+ import threading
20
+ from dataclasses import dataclass, asdict
21
+ from enum import Enum
22
+ from typing import Dict, List, Optional, Tuple
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ class VoteChoice(Enum):
28
+ """Voting options."""
29
+ YES = "yes" # Approve the proposal
30
+ NO = "no" # Reject the proposal
31
+ ABSTAIN = "abstain" # Participate without opinion (counts for quorum)
32
+
33
+
34
+ @dataclass
35
+ class Vote:
36
+ """A single vote on a NEP."""
37
+ vote_id: str
38
+ nep_id: str
39
+ voter_node_id: str
40
+ choice: VoteChoice
41
+ stake_at_vote: float # Stake when vote was cast (locked)
42
+ timestamp: float
43
+ signature: str # ECDSA signature
44
+ reason: str = "" # Optional reason for vote
45
+
46
+ def to_dict(self) -> Dict:
47
+ return {
48
+ "vote_id": self.vote_id,
49
+ "nep_id": self.nep_id,
50
+ "voter_node_id": self.voter_node_id,
51
+ "choice": self.choice.value,
52
+ "stake_at_vote": self.stake_at_vote,
53
+ "timestamp": self.timestamp,
54
+ "signature": self.signature,
55
+ "reason": self.reason,
56
+ }
57
+
58
+ @classmethod
59
+ def from_dict(cls, data: Dict) -> 'Vote':
60
+ return cls(
61
+ vote_id=data["vote_id"],
62
+ nep_id=data["nep_id"],
63
+ voter_node_id=data["voter_node_id"],
64
+ choice=VoteChoice(data["choice"]),
65
+ stake_at_vote=data["stake_at_vote"],
66
+ timestamp=data["timestamp"],
67
+ signature=data["signature"],
68
+ reason=data.get("reason", ""),
69
+ )
70
+
71
+
72
+ @dataclass
73
+ class VoteResult:
74
+ """Aggregated voting results for a NEP."""
75
+ nep_id: str
76
+
77
+ # Vote counts (number of voters)
78
+ yes_count: int = 0
79
+ no_count: int = 0
80
+ abstain_count: int = 0
81
+
82
+ # Stake-weighted votes
83
+ yes_stake: float = 0.0
84
+ no_stake: float = 0.0
85
+ abstain_stake: float = 0.0
86
+
87
+ # Thresholds
88
+ total_stake_voted: float = 0.0
89
+ total_network_stake: float = 0.0
90
+ approval_threshold: float = 0.66
91
+ quorum_threshold: float = 0.20
92
+
93
+ # Status
94
+ quorum_reached: bool = False
95
+ approved: bool = False
96
+
97
+ @property
98
+ def participation_rate(self) -> float:
99
+ """Percentage of network stake that voted."""
100
+ if self.total_network_stake == 0:
101
+ return 0.0
102
+ return self.total_stake_voted / self.total_network_stake
103
+
104
+ @property
105
+ def approval_rate(self) -> float:
106
+ """Percentage of voting stake that approved."""
107
+ yes_no_total = self.yes_stake + self.no_stake
108
+ if yes_no_total == 0:
109
+ return 0.0
110
+ return self.yes_stake / yes_no_total
111
+
112
+ def to_dict(self) -> Dict:
113
+ return {
114
+ "nep_id": self.nep_id,
115
+ "yes_count": self.yes_count,
116
+ "no_count": self.no_count,
117
+ "abstain_count": self.abstain_count,
118
+ "yes_stake": self.yes_stake,
119
+ "no_stake": self.no_stake,
120
+ "abstain_stake": self.abstain_stake,
121
+ "total_stake_voted": self.total_stake_voted,
122
+ "total_network_stake": self.total_network_stake,
123
+ "participation_rate": self.participation_rate,
124
+ "approval_rate": self.approval_rate,
125
+ "quorum_reached": self.quorum_reached,
126
+ "approved": self.approved,
127
+ }
128
+
129
+
130
+ class VotingSystem:
131
+ """
132
+ Manages NEP voting with stake-weighted governance.
133
+ """
134
+
135
+ def __init__(
136
+ self,
137
+ db_path: str = "nep_votes.db",
138
+ ledger=None, # NEUROLedger for stake lookups
139
+ ):
140
+ self.db_path = db_path
141
+ self.ledger = ledger
142
+ self.lock = threading.Lock()
143
+
144
+ self._init_db()
145
+
146
+ def _init_db(self):
147
+ """Initialize voting database."""
148
+ with self.lock:
149
+ with sqlite3.connect(self.db_path, timeout=60.0) as conn:
150
+ conn.execute("""
151
+ CREATE TABLE IF NOT EXISTS votes (
152
+ vote_id TEXT PRIMARY KEY,
153
+ nep_id TEXT NOT NULL,
154
+ voter_node_id TEXT NOT NULL,
155
+ choice TEXT NOT NULL,
156
+ stake_at_vote REAL NOT NULL,
157
+ timestamp REAL NOT NULL,
158
+ signature TEXT NOT NULL,
159
+ reason TEXT DEFAULT '',
160
+ UNIQUE(nep_id, voter_node_id)
161
+ )
162
+ """)
163
+
164
+ conn.execute("""
165
+ CREATE INDEX IF NOT EXISTS idx_votes_nep
166
+ ON votes(nep_id)
167
+ """)
168
+
169
+ def cast_vote(
170
+ self,
171
+ nep_id: str,
172
+ voter_node_id: str,
173
+ choice: VoteChoice,
174
+ signature: str,
175
+ reason: str = "",
176
+ nep_registry=None,
177
+ ) -> Tuple[bool, str]:
178
+ """
179
+ Cast a vote on a NEP.
180
+
181
+ Requirements:
182
+ 1. NEP must be in VOTING status
183
+ 2. Voting period must be active
184
+ 3. Voter must have stake > 0
185
+ 4. Vote must be signed
186
+
187
+ Returns: (success, message)
188
+ """
189
+ # Check NEP status
190
+ if nep_registry:
191
+ nep = nep_registry.get_proposal(nep_id)
192
+ if not nep:
193
+ return False, "NEP not found"
194
+ if not nep.is_voting_active():
195
+ return False, f"Voting not active for {nep_id}"
196
+
197
+ # Get voter's stake
198
+ stake = 0.0
199
+ if self.ledger:
200
+ stake = self.ledger.get_local_stake(voter_node_id)
201
+ if stake <= 0:
202
+ return False, "Must have staked NEURO to vote"
203
+ else:
204
+ # Test mode - assume 100 stake
205
+ stake = 100.0
206
+
207
+ # Check if already voted
208
+ with sqlite3.connect(self.db_path, timeout=60.0) as conn:
209
+ existing = conn.execute(
210
+ "SELECT vote_id FROM votes WHERE nep_id = ? AND voter_node_id = ?",
211
+ (nep_id, voter_node_id)
212
+ ).fetchone()
213
+
214
+ if existing:
215
+ return False, "Already voted on this NEP"
216
+
217
+ # Create vote
218
+ vote_id = hashlib.sha256(
219
+ f"{nep_id}:{voter_node_id}:{time.time()}".encode()
220
+ ).hexdigest()[:32]
221
+
222
+ vote = Vote(
223
+ vote_id=vote_id,
224
+ nep_id=nep_id,
225
+ voter_node_id=voter_node_id,
226
+ choice=choice,
227
+ stake_at_vote=stake,
228
+ timestamp=time.time(),
229
+ signature=signature,
230
+ reason=reason,
231
+ )
232
+
233
+ # Store vote
234
+ with self.lock:
235
+ with sqlite3.connect(self.db_path, timeout=60.0) as conn:
236
+ conn.execute("""
237
+ INSERT INTO votes
238
+ (vote_id, nep_id, voter_node_id, choice, stake_at_vote,
239
+ timestamp, signature, reason)
240
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
241
+ """, (
242
+ vote.vote_id,
243
+ vote.nep_id,
244
+ vote.voter_node_id,
245
+ vote.choice.value,
246
+ vote.stake_at_vote,
247
+ vote.timestamp,
248
+ vote.signature,
249
+ vote.reason,
250
+ ))
251
+
252
+ logger.info(
253
+ f"Vote cast: {voter_node_id[:16]}... voted {choice.value} "
254
+ f"on {nep_id} with {stake:.2f} stake"
255
+ )
256
+
257
+ return True, f"Vote recorded: {choice.value} with {stake:.2f} stake"
258
+
259
+ def get_vote_tally(
260
+ self,
261
+ nep_id: str,
262
+ approval_threshold: float = 0.66,
263
+ quorum_threshold: float = 0.20,
264
+ ) -> VoteResult:
265
+ """
266
+ Get the current vote tally for a NEP.
267
+ """
268
+ result = VoteResult(
269
+ nep_id=nep_id,
270
+ approval_threshold=approval_threshold,
271
+ quorum_threshold=quorum_threshold,
272
+ )
273
+
274
+ with sqlite3.connect(self.db_path, timeout=60.0) as conn:
275
+ votes = conn.execute(
276
+ "SELECT choice, stake_at_vote FROM votes WHERE nep_id = ?",
277
+ (nep_id,)
278
+ ).fetchall()
279
+
280
+ for choice_str, stake in votes:
281
+ choice = VoteChoice(choice_str)
282
+
283
+ if choice == VoteChoice.YES:
284
+ result.yes_count += 1
285
+ result.yes_stake += stake
286
+ elif choice == VoteChoice.NO:
287
+ result.no_count += 1
288
+ result.no_stake += stake
289
+ else:
290
+ result.abstain_count += 1
291
+ result.abstain_stake += stake
292
+
293
+ result.total_stake_voted = (
294
+ result.yes_stake + result.no_stake + result.abstain_stake
295
+ )
296
+
297
+ # Get total network stake
298
+ if self.ledger:
299
+ # Query total staked from ledger
300
+ result.total_network_stake = self._get_total_network_stake()
301
+ else:
302
+ # Test mode - assume voted stake is 50% of network
303
+ result.total_network_stake = result.total_stake_voted * 2
304
+
305
+ # Check quorum
306
+ if result.total_network_stake > 0:
307
+ result.quorum_reached = (
308
+ result.participation_rate >= quorum_threshold
309
+ )
310
+
311
+ # Check approval (only if quorum reached)
312
+ if result.quorum_reached:
313
+ result.approved = result.approval_rate >= approval_threshold
314
+
315
+ return result
316
+
317
+ def _get_total_network_stake(self) -> float:
318
+ """Get total staked NEURO in the network."""
319
+ if not self.ledger:
320
+ return 0.0
321
+
322
+ try:
323
+ with sqlite3.connect(self.ledger.db_path, timeout=60.0) as conn:
324
+ row = conn.execute(
325
+ "SELECT SUM(amount) FROM stakes WHERE locked_until > ?",
326
+ (time.time(),)
327
+ ).fetchone()
328
+ return row[0] if row and row[0] else 0.0
329
+ except Exception as e:
330
+ logger.error(f"Failed to get network stake: {e}")
331
+ return 0.0
332
+
333
+ def get_voter_history(self, voter_node_id: str) -> List[Vote]:
334
+ """Get all votes by a node."""
335
+ with sqlite3.connect(self.db_path, timeout=60.0) as conn:
336
+ rows = conn.execute(
337
+ "SELECT vote_id, nep_id, voter_node_id, choice, "
338
+ "stake_at_vote, timestamp, signature, reason "
339
+ "FROM votes WHERE voter_node_id = ? ORDER BY timestamp DESC",
340
+ (voter_node_id,)
341
+ ).fetchall()
342
+
343
+ return [
344
+ Vote(
345
+ vote_id=row[0],
346
+ nep_id=row[1],
347
+ voter_node_id=row[2],
348
+ choice=VoteChoice(row[3]),
349
+ stake_at_vote=row[4],
350
+ timestamp=row[5],
351
+ signature=row[6],
352
+ reason=row[7],
353
+ )
354
+ for row in rows
355
+ ]
356
+
357
+ def finalize_voting(
358
+ self,
359
+ nep_id: str,
360
+ nep_registry,
361
+ ) -> Tuple[bool, str, VoteResult]:
362
+ """
363
+ Finalize voting and update NEP status.
364
+
365
+ Called when voting period ends.
366
+ Returns: (success, message, final_result)
367
+ """
368
+ nep = nep_registry.get_proposal(nep_id)
369
+ if not nep:
370
+ return False, "NEP not found", None
371
+
372
+ # Get final tally
373
+ result = self.get_vote_tally(
374
+ nep_id,
375
+ approval_threshold=nep.approval_threshold,
376
+ quorum_threshold=nep.quorum_threshold,
377
+ )
378
+
379
+ if result.approved:
380
+ # Calculate activation block (e.g., 10000 blocks from now)
381
+ activation_block = self._get_current_block() + nep.upgrade_path.activation_delay_blocks
382
+
383
+ nep_registry.update_status(
384
+ nep_id,
385
+ NEPStatus.SCHEDULED,
386
+ activation_block=activation_block,
387
+ )
388
+
389
+ message = (
390
+ f"Approved! Activation scheduled at block {activation_block}. "
391
+ f"Approval: {result.approval_rate:.1%}, "
392
+ f"Participation: {result.participation_rate:.1%}"
393
+ )
394
+
395
+ elif result.quorum_reached:
396
+ nep_registry.update_status(nep_id, NEPStatus.REJECTED)
397
+ message = (
398
+ f"Rejected. Approval: {result.approval_rate:.1%} "
399
+ f"(needed {nep.approval_threshold:.1%})"
400
+ )
401
+
402
+ else:
403
+ nep_registry.update_status(nep_id, NEPStatus.REJECTED)
404
+ message = (
405
+ f"Failed to reach quorum. Participation: {result.participation_rate:.1%} "
406
+ f"(needed {nep.quorum_threshold:.1%})"
407
+ )
408
+
409
+ logger.info(f"Voting finalized for {nep_id}: {message}")
410
+
411
+ return True, message, result
412
+
413
+ def _get_current_block(self) -> int:
414
+ """
415
+ Get current block number.
416
+
417
+ In a true blockchain, this would query the chain.
418
+ For NeuroShard, we use a logical block based on proof count.
419
+ """
420
+ if self.ledger:
421
+ try:
422
+ stats = self.ledger.get_global_stats()
423
+ # Use proof count as "block height"
424
+ return stats.total_proofs_processed
425
+ except:
426
+ pass
427
+ return int(time.time() / 60) # Fallback: 1 "block" per minute
428
+
429
+
430
+ # Module-level convenience functions
431
+ from .proposal import NEPStatus
432
+
433
+ def cast_vote(
434
+ voting_system: VotingSystem,
435
+ nep_id: str,
436
+ voter_node_id: str,
437
+ choice: VoteChoice,
438
+ signature: str,
439
+ reason: str = "",
440
+ nep_registry=None,
441
+ ) -> Tuple[bool, str]:
442
+ """Cast a vote on a NEP."""
443
+ return voting_system.cast_vote(
444
+ nep_id, voter_node_id, choice, signature, reason, nep_registry
445
+ )
446
+
447
+
448
+ def get_vote_tally(
449
+ voting_system: VotingSystem,
450
+ nep_id: str,
451
+ ) -> VoteResult:
452
+ """Get current vote tally for a NEP."""
453
+ return voting_system.get_vote_tally(nep_id)
@@ -0,0 +1,30 @@
1
+ # neuroshard/core/model/__init__.py
2
+ """
3
+ Model components for NeuroShard.
4
+
5
+ - dynamic: DynamicNeuroNode, DynamicLayerPool, DynamicNeuroLLM
6
+ - llm: NeuroLLMModel, NeuroDecoderLayer
7
+ - tokenizer: NeuroTokenizer, get_neuro_tokenizer
8
+ - registry: TokenizerConfig
9
+ - scaler: ArchitectureScaler
10
+ """
11
+
12
+ from neuroshard.core.model.dynamic import (
13
+ DynamicNeuroNode,
14
+ DynamicLayerPool,
15
+ DynamicNeuroLLM,
16
+ create_dynamic_node,
17
+ )
18
+
19
+ # Lazy imports to avoid circular dependencies
20
+ def get_tokenizer(*args, **kwargs):
21
+ from neuroshard.core.model.tokenizer import get_neuro_tokenizer
22
+ return get_neuro_tokenizer(*args, **kwargs)
23
+
24
+ __all__ = [
25
+ 'DynamicNeuroNode',
26
+ 'DynamicLayerPool',
27
+ 'DynamicNeuroLLM',
28
+ 'create_dynamic_node',
29
+ 'get_tokenizer',
30
+ ]