1
1
from collections .abc import Mapping
2
2
from dataclasses import dataclass
3
3
from hashlib import sha256
4
+ from random import randint
4
5
from types import SimpleNamespace
5
6
from typing import Any , Optional , Union , TypedDict
6
7
from unittest .mock import MagicMock , patch
@@ -358,6 +359,104 @@ def set_difficulty(self, netuid: int, difficulty: int) -> None:
358
359
359
360
subtensor_state ["Difficulty" ][netuid ][self .block_number ] = difficulty
360
361
362
+ def _register_neuron (self , netuid : int , hotkey : str , coldkey : str ) -> int :
363
+ subtensor_state = self .chain_state ["SubtensorModule" ]
364
+ if netuid not in subtensor_state ["NetworksAdded" ]:
365
+ raise Exception ("Subnet does not exist" )
366
+
367
+ subnetwork_n = self ._get_most_recent_storage (
368
+ subtensor_state ["SubnetworkN" ][netuid ]
369
+ )
370
+
371
+ if subnetwork_n > 0 and any (
372
+ self ._get_most_recent_storage (subtensor_state ["Keys" ][netuid ][uid ])
373
+ == hotkey
374
+ for uid in range (subnetwork_n )
375
+ ):
376
+ # already_registered
377
+ raise Exception ("Hotkey already registered" )
378
+ else :
379
+ # Not found
380
+ if subnetwork_n >= self ._get_most_recent_storage (
381
+ subtensor_state ["MaxAllowedUids" ][netuid ]
382
+ ):
383
+ # Subnet full, replace neuron randomly
384
+ uid = randint (0 , subnetwork_n - 1 )
385
+ else :
386
+ # Subnet not full, add new neuron
387
+ # Append as next uid and increment subnetwork_n
388
+ uid = subnetwork_n
389
+ subtensor_state ["SubnetworkN" ][netuid ][self .block_number ] = (
390
+ subnetwork_n + 1
391
+ )
392
+
393
+ subtensor_state ["Stake" ][hotkey ] = {}
394
+ subtensor_state ["Stake" ][hotkey ][coldkey ] = {}
395
+ subtensor_state ["Stake" ][hotkey ][coldkey ][self .block_number ] = 0
396
+
397
+ subtensor_state ["Uids" ][netuid ][hotkey ] = {}
398
+ subtensor_state ["Uids" ][netuid ][hotkey ][self .block_number ] = uid
399
+
400
+ subtensor_state ["Keys" ][netuid ][uid ] = {}
401
+ subtensor_state ["Keys" ][netuid ][uid ][self .block_number ] = hotkey
402
+
403
+ subtensor_state ["Owner" ][hotkey ] = {}
404
+ subtensor_state ["Owner" ][hotkey ][self .block_number ] = coldkey
405
+
406
+ subtensor_state ["Active" ][netuid ][uid ] = {}
407
+ subtensor_state ["Active" ][netuid ][uid ][self .block_number ] = True
408
+
409
+ subtensor_state ["LastUpdate" ][netuid ][uid ] = {}
410
+ subtensor_state ["LastUpdate" ][netuid ][uid ][self .block_number ] = (
411
+ self .block_number
412
+ )
413
+
414
+ subtensor_state ["Rank" ][netuid ][uid ] = {}
415
+ subtensor_state ["Rank" ][netuid ][uid ][self .block_number ] = 0.0
416
+
417
+ subtensor_state ["Emission" ][netuid ][uid ] = {}
418
+ subtensor_state ["Emission" ][netuid ][uid ][self .block_number ] = 0.0
419
+
420
+ subtensor_state ["Incentive" ][netuid ][uid ] = {}
421
+ subtensor_state ["Incentive" ][netuid ][uid ][self .block_number ] = 0.0
422
+
423
+ subtensor_state ["Consensus" ][netuid ][uid ] = {}
424
+ subtensor_state ["Consensus" ][netuid ][uid ][self .block_number ] = 0.0
425
+
426
+ subtensor_state ["Trust" ][netuid ][uid ] = {}
427
+ subtensor_state ["Trust" ][netuid ][uid ][self .block_number ] = 0.0
428
+
429
+ subtensor_state ["ValidatorTrust" ][netuid ][uid ] = {}
430
+ subtensor_state ["ValidatorTrust" ][netuid ][uid ][self .block_number ] = 0.0
431
+
432
+ subtensor_state ["Dividends" ][netuid ][uid ] = {}
433
+ subtensor_state ["Dividends" ][netuid ][uid ][self .block_number ] = 0.0
434
+
435
+ subtensor_state ["PruningScores" ][netuid ][uid ] = {}
436
+ subtensor_state ["PruningScores" ][netuid ][uid ][self .block_number ] = 0.0
437
+
438
+ subtensor_state ["ValidatorPermit" ][netuid ][uid ] = {}
439
+ subtensor_state ["ValidatorPermit" ][netuid ][uid ][self .block_number ] = False
440
+
441
+ subtensor_state ["Weights" ][netuid ][uid ] = {}
442
+ subtensor_state ["Weights" ][netuid ][uid ][self .block_number ] = []
443
+
444
+ subtensor_state ["Bonds" ][netuid ][uid ] = {}
445
+ subtensor_state ["Bonds" ][netuid ][uid ][self .block_number ] = []
446
+
447
+ subtensor_state ["Axons" ][netuid ][hotkey ] = {}
448
+ subtensor_state ["Axons" ][netuid ][hotkey ][self .block_number ] = {}
449
+
450
+ subtensor_state ["Prometheus" ][netuid ][hotkey ] = {}
451
+ subtensor_state ["Prometheus" ][netuid ][hotkey ][self .block_number ] = {}
452
+
453
+ if hotkey not in subtensor_state ["IsNetworkMember" ]:
454
+ subtensor_state ["IsNetworkMember" ][hotkey ] = {}
455
+ subtensor_state ["IsNetworkMember" ][hotkey ][netuid ] = {}
456
+ subtensor_state ["IsNetworkMember" ][hotkey ][netuid ][self .block_number ] = True
457
+
458
+ return uid
459
+
361
460
@staticmethod
362
461
def _convert_to_balance (balance : Union ["Balance" , float , int ]) -> "Balance" :
363
462
if isinstance (balance , float ):
@@ -368,6 +467,37 @@ def _convert_to_balance(balance: Union["Balance", float, int]) -> "Balance":
368
467
369
468
return balance
370
469
470
+ def force_register_neuron (
471
+ self ,
472
+ netuid : int ,
473
+ hotkey : str ,
474
+ coldkey : str ,
475
+ stake : Union ["Balance" , float , int ] = Balance (0 ),
476
+ balance : Union ["Balance" , float , int ] = Balance (0 ),
477
+ ) -> int :
478
+ """
479
+ Force register a neuron on the mock chain, returning the UID.
480
+ """
481
+ stake = self ._convert_to_balance (stake )
482
+ balance = self ._convert_to_balance (balance )
483
+
484
+ subtensor_state = self .chain_state ["SubtensorModule" ]
485
+ if netuid not in subtensor_state ["NetworksAdded" ]:
486
+ raise Exception ("Subnet does not exist" )
487
+
488
+ uid = self ._register_neuron (netuid = netuid , hotkey = hotkey , coldkey = coldkey )
489
+
490
+ subtensor_state ["TotalStake" ][self .block_number ] = (
491
+ self ._get_most_recent_storage (subtensor_state ["TotalStake" ]) + stake .rao
492
+ )
493
+ subtensor_state ["Stake" ][hotkey ][coldkey ][self .block_number ] = stake .rao
494
+
495
+ if balance .rao > 0 :
496
+ self .force_set_balance (coldkey , balance )
497
+ self .force_set_balance (coldkey , balance )
498
+
499
+ return uid
500
+
371
501
def force_set_balance (
372
502
self , ss58_address : str , balance : Union ["Balance" , float , int ] = Balance (0 )
373
503
) -> tuple [bool , Optional [str ]]:
0 commit comments