@@ -571,9 +571,133 @@ impl<T: Config> Pallet<T> {
571571 ) ;
572572 }
573573
574- let current_stake = Self :: get_total_stake_for_hotkey ( & hotkey) ;
574+ // --- 13. Join the Senate if eligible.
575+ // Returns the replaced member, if any.
576+ let _ = Self :: join_senate_if_eligible ( & hotkey) ?;
577+
578+ // --- 14. Force all members on root to become a delegate.
579+ if !Self :: hotkey_is_delegate ( & hotkey) {
580+ Self :: delegate_hotkey ( & hotkey, 11_796 ) ; // 18% cut defaulted.
581+ }
582+
583+ // --- 15. Update the registration counters for both the block and interval.
584+ #[ allow( clippy:: arithmetic_side_effects) ]
585+ // note this RA + clippy false positive is a known substrate issue
586+ RegistrationsThisInterval :: < T > :: mutate ( root_netuid, |val| * val += 1 ) ;
587+ #[ allow( clippy:: arithmetic_side_effects) ]
588+ // note this RA + clippy false positive is a known substrate issue
589+ RegistrationsThisBlock :: < T > :: mutate ( root_netuid, |val| * val += 1 ) ;
590+
591+ // --- 16. Log and announce the successful registration.
592+ log:: info!(
593+ "RootRegistered(netuid:{:?} uid:{:?} hotkey:{:?})" ,
594+ root_netuid,
595+ subnetwork_uid,
596+ hotkey
597+ ) ;
598+ Self :: deposit_event ( Event :: NeuronRegistered ( root_netuid, subnetwork_uid, hotkey) ) ;
599+
600+ // --- 17. Finish and return success.
601+ Ok ( ( ) )
602+ }
603+
604+ // Checks if a hotkey should be a member of the Senate, and if so, adds them.
605+ //
606+ // This function is responsible for adding a hotkey to the Senate if they meet the requirements.
607+ // The root key with the least stake is pruned in the event of a filled membership.
608+ //
609+ // # Arguments:
610+ // * 'origin': Represents the origin of the call.
611+ // * 'hotkey': The hotkey that the user wants to register to the root network.
612+ //
613+ // # Returns:
614+ // * 'DispatchResult': A result type indicating success or failure of the registration.
615+ //
616+ pub fn do_adjust_senate ( origin : T :: RuntimeOrigin , hotkey : T :: AccountId ) -> DispatchResult {
617+ // --- 0. Get the unique identifier (UID) for the root network.
618+ let root_netuid: u16 = Self :: get_root_netuid ( ) ;
619+ ensure ! (
620+ Self :: if_subnet_exist( root_netuid) ,
621+ Error :: <T >:: RootNetworkDoesNotExist
622+ ) ;
623+
624+ // --- 1. Ensure that the call originates from a signed source and retrieve the caller's account ID (coldkey).
625+ let coldkey = ensure_signed ( origin) ?;
626+ log:: info!(
627+ "do_root_register( coldkey: {:?}, hotkey: {:?} )" ,
628+ coldkey,
629+ hotkey
630+ ) ;
631+
632+ // --- 2. Check if the hotkey is already registered to the root network. If not, error out.
633+ ensure ! (
634+ Uids :: <T >:: contains_key( root_netuid, & hotkey) ,
635+ Error :: <T >:: HotKeyNotRegisteredInSubNet
636+ ) ;
637+
638+ // --- 3. Create a network account for the user if it doesn't exist.
639+ Self :: create_account_if_non_existent ( & coldkey, & hotkey) ;
640+
641+ // --- 4. Join the Senate if eligible.
642+ // Returns the replaced member, if any.
643+ let replaced = Self :: join_senate_if_eligible ( & hotkey) ?;
644+
645+ if replaced. is_none ( ) {
646+ // Not eligible to join the Senate, or no replacement needed.
647+ // Check if the hotkey is *now* a member of the Senate.
648+ // Otherwise, error out.
649+ ensure ! (
650+ T :: SenateMembers :: is_member( & hotkey) ,
651+ Error :: <T >:: StakeTooLowForRoot , // Had less stake than the lowest stake incumbent.
652+ ) ;
653+ }
654+
655+ // --- 5. Log and announce the successful Senate adjustment.
656+ log:: info!(
657+ "SenateAdjusted(old_hotkey:{:?} hotkey:{:?})" ,
658+ replaced,
659+ hotkey
660+ ) ;
661+ Self :: deposit_event ( Event :: SenateAdjusted {
662+ old_member : replaced. cloned ( ) ,
663+ new_member : hotkey,
664+ } ) ;
665+
666+ // --- 6. Finish and return success.
667+ Ok ( ( ) )
668+ }
669+
670+ // Checks if a hotkey should be a member of the Senate, and if so, adds them.
671+ //
672+ // # Arguments:
673+ // * 'hotkey': The hotkey that the user wants to register to the root network.
674+ //
675+ // # Returns:
676+ // * 'Result<Option<&T::AccountId>, Error<T>>': A result containing the replaced member, if any.
677+ //
678+ fn join_senate_if_eligible ( hotkey : & T :: AccountId ) -> Result < Option < & T :: AccountId > , Error < T > > {
679+ // Get the root network UID.
680+ let root_netuid: u16 = Self :: get_root_netuid ( ) ;
681+
682+ // --- 1. Check the hotkey is registered in the root network.
683+ ensure ! (
684+ Uids :: <T >:: contains_key( root_netuid, hotkey) ,
685+ Error :: <T >:: HotKeyNotRegisteredInSubNet
686+ ) ;
687+
688+ // --- 2. Verify the hotkey is NOT already a member of the Senate.
689+ ensure ! (
690+ !T :: SenateMembers :: is_member( hotkey) ,
691+ Error :: <T >:: HotKeyAlreadyRegisteredInSubNet
692+ ) ;
693+
694+ // --- 3. Grab the hotkey's stake.
695+ let current_stake = Self :: get_total_stake_for_hotkey ( hotkey) ;
696+
697+ // Add the hotkey to the Senate.
575698 // If we're full, we'll swap out the lowest stake member.
576699 let members = T :: SenateMembers :: members ( ) ;
700+ let last: Option < & T :: AccountId > = None ;
577701 if ( members. len ( ) as u32 ) == T :: SenateMembers :: max_members ( ) {
578702 let mut sorted_members = members. clone ( ) ;
579703 sorted_members. sort_by ( |a, b| {
@@ -587,34 +711,17 @@ impl<T: Config> Pallet<T> {
587711 let last_stake = Self :: get_total_stake_for_hotkey ( last) ;
588712
589713 if last_stake < current_stake {
590- T :: SenateMembers :: swap_member ( last, & hotkey) . map_err ( |e| e. error ) ?;
591- T :: TriumvirateInterface :: remove_votes ( last) ?;
714+ // Swap the member with the lowest stake.
715+ T :: SenateMembers :: swap_member ( last, hotkey)
716+ . map_err ( |_| Error :: < T > :: CouldNotJoinSenate ) ?;
592717 }
593718 }
594719 } else {
595- T :: SenateMembers :: add_member ( & hotkey) . map_err ( |e| e . error ) ?;
720+ T :: SenateMembers :: add_member ( hotkey) . map_err ( |_| Error :: < T > :: CouldNotJoinSenate ) ?;
596721 }
597722
598- // --- 13. Force all members on root to become a delegate.
599- if !Self :: hotkey_is_delegate ( & hotkey) {
600- Self :: delegate_hotkey ( & hotkey, 11_796 ) ; // 18% cut defaulted.
601- }
602-
603- // --- 14. Update the registration counters for both the block and interval.
604- RegistrationsThisInterval :: < T > :: mutate ( root_netuid, |val| val. saturating_inc ( ) ) ;
605- RegistrationsThisBlock :: < T > :: mutate ( root_netuid, |val| val. saturating_inc ( ) ) ;
606-
607- // --- 15. Log and announce the successful registration.
608- log:: info!(
609- "RootRegistered(netuid:{:?} uid:{:?} hotkey:{:?})" ,
610- root_netuid,
611- subnetwork_uid,
612- hotkey
613- ) ;
614- Self :: deposit_event ( Event :: NeuronRegistered ( root_netuid, subnetwork_uid, hotkey) ) ;
615-
616- // --- 16. Finish and return success.
617- Ok ( ( ) )
723+ // Return the swapped out member, if any.
724+ Ok ( last)
618725 }
619726
620727 pub fn do_set_root_weights (
0 commit comments