@@ -365,6 +365,9 @@ pub mod pallet {
365365 #[ pallet:: storage] // --- MAP ( hot ) --> cold | Returns the controlling coldkey for a hotkey.
366366 pub type Owner < T : Config > =
367367 StorageMap < _ , Blake2_128Concat , T :: AccountId , T :: AccountId , ValueQuery , DefaultAccount < T > > ;
368+ #[ pallet:: storage] // --- MAP ( cold ) --> Vec<hot> | Returns the vector of hotkeys controlled by this coldkey.
369+ pub type OwnedHotkeys < T : Config > =
370+ StorageMap < _ , Blake2_128Concat , T :: AccountId , Vec < T :: AccountId > , ValueQuery > ;
368371 #[ pallet:: storage] // --- MAP ( hot ) --> take | Returns the hotkey delegation take. And signals that this key is open for delegation.
369372 pub type Delegates < T : Config > =
370373 StorageMap < _ , Blake2_128Concat , T :: AccountId , u16 , ValueQuery , DefaultDefaultTake < T > > ;
@@ -379,6 +382,9 @@ pub mod pallet {
379382 ValueQuery ,
380383 DefaultAccountTake < T > ,
381384 > ;
385+ #[ pallet:: storage] // --- DMAP ( cold ) --> Vec<hot> | Maps coldkey to hotkeys that stake to it
386+ pub type StakingHotkeys < T : Config > =
387+ StorageMap < _ , Blake2_128Concat , T :: AccountId , Vec < T :: AccountId > , ValueQuery > ;
382388 /// -- ITEM (switches liquid alpha on)
383389 #[ pallet:: type_value]
384390 pub fn DefaultLiquidAlpha < T : Config > ( ) -> bool {
@@ -1208,6 +1214,13 @@ pub mod pallet {
12081214 // Fill stake information.
12091215 Owner :: < T > :: insert ( hotkey. clone ( ) , coldkey. clone ( ) ) ;
12101216
1217+ // Update OwnedHotkeys map
1218+ let mut hotkeys = OwnedHotkeys :: < T > :: get ( coldkey) ;
1219+ if !hotkeys. contains ( hotkey) {
1220+ hotkeys. push ( hotkey. clone ( ) ) ;
1221+ OwnedHotkeys :: < T > :: insert ( coldkey, hotkeys) ;
1222+ }
1223+
12111224 TotalHotkeyStake :: < T > :: insert ( hotkey. clone ( ) , stake) ;
12121225 TotalColdkeyStake :: < T > :: insert (
12131226 coldkey. clone ( ) ,
@@ -1219,6 +1232,13 @@ pub mod pallet {
12191232
12201233 Stake :: < T > :: insert ( hotkey. clone ( ) , coldkey. clone ( ) , stake) ;
12211234
1235+ // Update StakingHotkeys map
1236+ let mut staking_hotkeys = StakingHotkeys :: < T > :: get ( coldkey) ;
1237+ if !staking_hotkeys. contains ( hotkey) {
1238+ staking_hotkeys. push ( hotkey. clone ( ) ) ;
1239+ StakingHotkeys :: < T > :: insert ( coldkey, staking_hotkeys) ;
1240+ }
1241+
12221242 next_uid = next_uid. checked_add ( 1 ) . expect (
12231243 "should not have total number of hotkey accounts larger than u16::MAX" ,
12241244 ) ;
@@ -1329,7 +1349,11 @@ pub mod pallet {
13291349 // Storage version v4 -> v5
13301350 . saturating_add ( migration:: migrate_delete_subnet_3 :: < T > ( ) )
13311351 // Doesn't check storage version. TODO: Remove after upgrade
1332- . saturating_add ( migration:: migration5_total_issuance :: < T > ( false ) ) ;
1352+ . saturating_add ( migration:: migration5_total_issuance :: < T > ( false ) )
1353+ // Populate OwnedHotkeys map for coldkey swap. Doesn't update storage vesion.
1354+ . saturating_add ( migration:: migrate_populate_owned :: < T > ( ) )
1355+ // Populate StakingHotkeys map for coldkey swap. Doesn't update storage vesion.
1356+ . saturating_add ( migration:: migrate_populate_staking_hotkeys :: < T > ( ) ) ;
13331357
13341358 weight
13351359 }
@@ -1974,6 +1998,60 @@ pub mod pallet {
19741998 Self :: do_swap_hotkey ( origin, & hotkey, & new_hotkey)
19751999 }
19762000
2001+ /// The extrinsic for user to change the coldkey associated with their account.
2002+ ///
2003+ /// # Arguments
2004+ ///
2005+ /// * `origin` - The origin of the call, must be signed by the old coldkey.
2006+ /// * `old_coldkey` - The current coldkey associated with the account.
2007+ /// * `new_coldkey` - The new coldkey to be associated with the account.
2008+ ///
2009+ /// # Returns
2010+ ///
2011+ /// Returns a `DispatchResultWithPostInfo` indicating success or failure of the operation.
2012+ ///
2013+ /// # Weight
2014+ ///
2015+ /// Weight is calculated based on the number of database reads and writes.
2016+ #[ pallet:: call_index( 71 ) ]
2017+ #[ pallet:: weight( ( Weight :: from_parts( 1_940_000_000 , 0 )
2018+ . saturating_add( T :: DbWeight :: get( ) . reads( 272 ) )
2019+ . saturating_add( T :: DbWeight :: get( ) . writes( 527 ) ) , DispatchClass :: Operational , Pays :: No ) ) ]
2020+ pub fn swap_coldkey (
2021+ origin : OriginFor < T > ,
2022+ old_coldkey : T :: AccountId ,
2023+ new_coldkey : T :: AccountId ,
2024+ ) -> DispatchResultWithPostInfo {
2025+ Self :: do_swap_coldkey ( origin, & old_coldkey, & new_coldkey)
2026+ }
2027+
2028+ /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey.
2029+ ///
2030+ /// # Arguments
2031+ ///
2032+ /// * `origin` - The origin of the call, must be signed by the current coldkey.
2033+ /// * `hotkey` - The hotkey associated with the stakes to be unstaked.
2034+ /// * `new_coldkey` - The new coldkey to receive the unstaked tokens.
2035+ ///
2036+ /// # Returns
2037+ ///
2038+ /// Returns a `DispatchResult` indicating success or failure of the operation.
2039+ ///
2040+ /// # Weight
2041+ ///
2042+ /// Weight is calculated based on the number of database reads and writes.
2043+ #[ pallet:: call_index( 72 ) ]
2044+ #[ pallet:: weight( ( Weight :: from_parts( 1_940_000_000 , 0 )
2045+ . saturating_add( T :: DbWeight :: get( ) . reads( 272 ) )
2046+ . saturating_add( T :: DbWeight :: get( ) . writes( 527 ) ) , DispatchClass :: Operational , Pays :: No ) ) ]
2047+ pub fn unstake_all_and_transfer_to_new_coldkey (
2048+ origin : OriginFor < T > ,
2049+ new_coldkey : T :: AccountId ,
2050+ ) -> DispatchResult {
2051+ let current_coldkey = ensure_signed ( origin) ?;
2052+ Self :: do_unstake_all_and_transfer_to_new_coldkey ( current_coldkey, new_coldkey)
2053+ }
2054+
19772055 // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------
19782056
19792057 // ==================================
0 commit comments