Skip to content

Commit 993f033

Browse files
committed
clean up swap coldkey
1 parent 33bdf7b commit 993f033

File tree

5 files changed

+91
-275
lines changed

5 files changed

+91
-275
lines changed

pallets/subtensor/src/macros/dispatches.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ mod dispatches {
10901090
old_coldkey: T::AccountId,
10911091
new_coldkey: T::AccountId,
10921092
swap_cost: TaoCurrency,
1093-
) -> DispatchResultWithPostInfo {
1093+
) -> DispatchResult {
10941094
// Ensure it's called with root privileges (scheduler has root privileges)
10951095
ensure_root(origin)?;
10961096
log::debug!("swap_coldkey: {:?} -> {:?}", old_coldkey, new_coldkey);

pallets/subtensor/src/macros/genesis.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ mod genesis {
101101
netuid,
102102
U64F64::saturating_from_num(1_000_000_000),
103103
);
104-
// TotalColdkeyAlpha::<T>::insert(hotkey.clone(), netuid, 1_000_000_000);
105104
SubnetAlphaOut::<T>::insert(netuid, AlphaCurrency::from(1_000_000_000));
106105
let mut staking_hotkeys = StakingHotkeys::<T>::get(hotkey.clone());
107106
if !staking_hotkeys.contains(&hotkey) {
Lines changed: 86 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -1,228 +1,136 @@
11
use super::*;
2-
use frame_support::weights::Weight;
3-
use sp_core::Get;
42
use substrate_fixed::types::U64F64;
53

64
impl<T: Config> Pallet<T> {
7-
/// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey.
8-
///
9-
/// # Arguments
10-
///
11-
/// * `origin` - The origin of the call, which must be signed by the old coldkey.
12-
/// * `new_coldkey` - The account ID of the new coldkey.
13-
///
14-
/// # Returns
15-
///
16-
/// Returns a `DispatchResultWithPostInfo` indicating success or failure, along with the weight consumed.
17-
///
18-
/// # Errors
19-
///
20-
/// This function will return an error if:
21-
/// - The caller is not a valid signed origin.
22-
/// - The old coldkey (caller) is in arbitration.
23-
/// - The new coldkey is already associated with other hotkeys or is a hotkey itself.
24-
/// - There's not enough balance to pay for the swap.
25-
///
26-
/// # Events
27-
///
28-
/// Emits a `ColdkeySwapped` event when successful.
29-
///
30-
/// # Weight
31-
///
32-
/// Weight is tracked and updated throughout the function execution.
5+
/// Logic for the coldkey swap operation. Checks for collisions, balances, and cooldowns
6+
/// before executing the swap.
337
pub fn do_swap_coldkey(
348
old_coldkey: &T::AccountId,
359
new_coldkey: &T::AccountId,
3610
swap_cost: TaoCurrency,
37-
) -> DispatchResultWithPostInfo {
38-
// 2. Initialize the weight for this operation
39-
let mut weight: Weight = T::DbWeight::get().reads(2);
40-
// 3. Ensure the new coldkey is not associated with any hotkeys
11+
) -> DispatchResult {
4112
ensure!(
4213
StakingHotkeys::<T>::get(new_coldkey).is_empty(),
4314
Error::<T>::ColdKeyAlreadyAssociated
4415
);
45-
weight = weight.saturating_add(T::DbWeight::get().reads(1));
46-
47-
// 4. Ensure the new coldkey is not a hotkey
4816
ensure!(
4917
!Self::hotkey_account_exists(new_coldkey),
5018
Error::<T>::NewColdKeyIsHotkey
5119
);
52-
weight = weight.saturating_add(T::DbWeight::get().reads(1));
53-
54-
// 5. Swap the identity if the old coldkey has one
55-
if let Some(identity) = IdentitiesV2::<T>::take(old_coldkey) {
56-
IdentitiesV2::<T>::insert(new_coldkey, identity);
57-
}
58-
59-
// 6. Ensure sufficient balance for the swap cost
6020
ensure!(
6121
Self::can_remove_balance_from_coldkey_account(old_coldkey, swap_cost.into()),
6222
Error::<T>::NotEnoughBalanceToPaySwapColdKey
6323
);
6424

65-
// 7. Remove and recycle the swap cost from the old coldkey's account
66-
let actual_burn_amount =
67-
Self::remove_balance_from_coldkey_account(old_coldkey, swap_cost.into())?;
68-
Self::recycle_tao(actual_burn_amount);
25+
// Swap the identity if the old coldkey has one
26+
if let Some(identity) = IdentitiesV2::<T>::take(old_coldkey) {
27+
IdentitiesV2::<T>::insert(new_coldkey, identity);
28+
}
6929

70-
// 8. Update the weight for the balance operations
71-
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));
30+
// Remove and recycle the swap cost from the old coldkey's account
31+
let burn_amount = Self::remove_balance_from_coldkey_account(old_coldkey, swap_cost.into())?;
32+
Self::recycle_tao(burn_amount);
7233

73-
// 9. Perform the actual coldkey swap
74-
let _ = Self::perform_swap_coldkey(old_coldkey, new_coldkey, &mut weight);
34+
Self::perform_swap_coldkey(old_coldkey, new_coldkey)?;
7535

76-
// 10. Update the last transaction block for the new coldkey
7736
Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64());
78-
weight.saturating_accrue(T::DbWeight::get().writes(1));
7937

80-
// 11. Remove the coldkey swap scheduled record
8138
ColdkeySwapScheduled::<T>::remove(old_coldkey);
8239

83-
// 12. Emit the ColdkeySwapped event
8440
Self::deposit_event(Event::ColdkeySwapped {
8541
old_coldkey: old_coldkey.clone(),
8642
new_coldkey: new_coldkey.clone(),
8743
swap_cost,
8844
});
89-
90-
// 12. Return the result with the updated weight
91-
Ok(Some(weight).into())
45+
Ok(())
9246
}
9347

94-
/// Performs the actual coldkey swap operation, transferring all associated data and balances from the old coldkey to the new coldkey.
95-
///
96-
/// # Arguments
97-
///
98-
/// * `old_coldkey` - The account ID of the old coldkey.
99-
/// * `new_coldkey` - The account ID of the new coldkey.
100-
/// * `weight` - A mutable reference to the current transaction weight.
101-
///
102-
/// # Returns
103-
///
104-
/// Returns a `DispatchResult` indicating success or failure of the operation.
105-
///
106-
/// # Steps
107-
///
108-
/// 1. Swap TotalHotkeyColdkeyStakesThisInterval:
109-
/// - For each hotkey owned by the old coldkey, transfer its stake and block data to the new coldkey.
110-
///
111-
/// 2. Swap subnet ownership:
112-
/// - For each subnet, if the old coldkey is the owner, transfer ownership to the new coldkey.
113-
///
114-
/// 3. Swap Stakes:
115-
/// - For each hotkey staking for the old coldkey, transfer its stake to the new coldkey.
48+
/// Transfer all assets, stakes, subnet ownerships, and hotkey associations from `old_coldkey` to `new_coldkey`.
11649
///
117-
/// 4. Swap total coldkey stake:
118-
/// - Transfer the total stake from the old coldkey to the new coldkey.
119-
///
120-
/// 5. Swap StakingHotkeys:
121-
/// - Transfer the list of staking hotkeys from the old coldkey to the new coldkey.
122-
///
123-
/// 6. Swap hotkey owners:
124-
/// - For each hotkey owned by the old coldkey, transfer ownership to the new coldkey.
125-
/// - Update the list of owned hotkeys for both old and new coldkeys.
126-
///
127-
/// 7. Transfer remaining balance:
128-
/// - Transfer any remaining balance from the old coldkey to the new coldkey.
129-
///
130-
/// Throughout the process, the function updates the transaction weight to reflect the operations performed.
131-
///
132-
/// # Notes
133-
///
134-
/// This function is a critical part of the coldkey swap process and should be called only after all necessary checks and validations have been performed.
50+
/// # Warning
51+
/// This function performs NO validation checks. It assumes the caller has done all the checks before calling it.
13552
pub fn perform_swap_coldkey(
13653
old_coldkey: &T::AccountId,
13754
new_coldkey: &T::AccountId,
138-
weight: &mut Weight,
13955
) -> DispatchResult {
140-
// 1. Swap TotalHotkeyColdkeyStakesThisInterval
141-
// TotalHotkeyColdkeyStakesThisInterval: MAP ( hotkey, coldkey ) --> ( stake, block ) | Stake of the hotkey for the coldkey.
142-
// for hotkey in OwnedHotkeys::<T>::get(old_coldkey).iter() {
143-
// let (stake, block) =
144-
// TotalHotkeyColdkeyStakesThisInterval::<T>::get(&hotkey, old_coldkey);
145-
// TotalHotkeyColdkeyStakesThisInterval::<T>::remove(&hotkey, old_coldkey);
146-
// TotalHotkeyColdkeyStakesThisInterval::<T>::insert(&hotkey, new_coldkey, (stake, block));
147-
// weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2));
148-
// } (DEPRECATED)
149-
150-
// 2. Swap subnet owner.
151-
// SubnetOwner: MAP ( netuid ) --> (coldkey) | Owner of the subnet.
15256
for netuid in Self::get_all_subnet_netuids() {
153-
let subnet_owner = SubnetOwner::<T>::get(netuid);
154-
if subnet_owner == *old_coldkey {
155-
SubnetOwner::<T>::insert(netuid, new_coldkey.clone());
156-
}
157-
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));
57+
Self::transfer_subnet_ownership(netuid, old_coldkey, new_coldkey);
58+
Self::transfer_coldkey_stake(netuid, old_coldkey, new_coldkey);
59+
}
15860

159-
if let Some(old_auto_stake_hotkey) = AutoStakeDestination::<T>::get(old_coldkey, netuid)
160-
{
161-
AutoStakeDestination::<T>::remove(old_coldkey, netuid);
162-
AutoStakeDestination::<T>::insert(
163-
new_coldkey,
164-
netuid,
165-
old_auto_stake_hotkey.clone(),
166-
);
167-
AutoStakeDestinationColdkeys::<T>::mutate(old_auto_stake_hotkey, netuid, |v| {
168-
// Remove old/new coldkeys (avoid duplicates), then add the new one.
169-
v.retain(|c| *c != *old_coldkey && *c != *new_coldkey);
170-
v.push(new_coldkey.clone());
171-
});
172-
}
61+
Self::transfer_staking_hotkeys(old_coldkey, new_coldkey);
62+
Self::transfer_hotkeys_ownership(old_coldkey, new_coldkey);
63+
64+
// Transfer any remaining balance from old_coldkey to new_coldkey
65+
let remaining_balance = Self::get_coldkey_balance(old_coldkey);
66+
if remaining_balance > 0 {
67+
Self::kill_coldkey_account(old_coldkey, remaining_balance)?;
68+
Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance);
69+
}
70+
71+
Ok(())
72+
}
73+
74+
/// Transfer the ownership of the subnet to the new coldkey if it is owned by the old coldkey.
75+
fn transfer_subnet_ownership(
76+
netuid: NetUid,
77+
old_coldkey: &T::AccountId,
78+
new_coldkey: &T::AccountId,
79+
) {
80+
let subnet_owner = SubnetOwner::<T>::get(netuid);
81+
if subnet_owner == *old_coldkey {
82+
SubnetOwner::<T>::insert(netuid, new_coldkey.clone());
83+
}
84+
85+
if let Some(old_auto_stake_hotkey) = AutoStakeDestination::<T>::get(old_coldkey, netuid) {
86+
AutoStakeDestination::<T>::remove(old_coldkey, netuid);
87+
AutoStakeDestination::<T>::insert(new_coldkey, netuid, old_auto_stake_hotkey.clone());
88+
AutoStakeDestinationColdkeys::<T>::mutate(old_auto_stake_hotkey, netuid, |v| {
89+
// Remove old/new coldkeys (avoid duplicates), then add the new one.
90+
v.retain(|c| *c != *old_coldkey && *c != *new_coldkey);
91+
v.push(new_coldkey.clone());
92+
});
17393
}
94+
}
17495

175-
// 3. Swap Stake.
176-
// StakingHotkeys: MAP ( coldkey ) --> Vec( hotkey )
96+
/// Transfer the stake of all staking hotkeys linked to the old coldkey to the new coldkey.
97+
fn transfer_coldkey_stake(
98+
netuid: NetUid,
99+
old_coldkey: &T::AccountId,
100+
new_coldkey: &T::AccountId,
101+
) {
177102
for hotkey in StakingHotkeys::<T>::get(old_coldkey) {
178-
// 3.1 Swap Alpha
179-
for netuid in Self::get_all_subnet_netuids() {
180-
// Get the stake on the old (hot,coldkey) account.
181-
let old_alpha: U64F64 = Alpha::<T>::get((&hotkey, old_coldkey, netuid));
182-
// Get the stake on the new (hot,coldkey) account.
183-
let new_alpha: U64F64 = Alpha::<T>::get((&hotkey, new_coldkey, netuid));
184-
// Add the stake to new account.
185-
Alpha::<T>::insert(
186-
(&hotkey, new_coldkey, netuid),
187-
new_alpha.saturating_add(old_alpha),
103+
// Get the stake on the old (hot,coldkey) account.
104+
let old_alpha: U64F64 = Alpha::<T>::get((&hotkey, old_coldkey, netuid));
105+
// Get the stake on the new (hot,coldkey) account.
106+
let new_alpha: U64F64 = Alpha::<T>::get((&hotkey, new_coldkey, netuid));
107+
// Add the stake to new account.
108+
Alpha::<T>::insert(
109+
(&hotkey, new_coldkey, netuid),
110+
new_alpha.saturating_add(old_alpha),
111+
);
112+
// Remove the value from the old account.
113+
Alpha::<T>::remove((&hotkey, old_coldkey, netuid));
114+
115+
if new_alpha.saturating_add(old_alpha) > U64F64::from(0u64) {
116+
Self::transfer_root_claimed_for_new_keys(
117+
netuid,
118+
&hotkey,
119+
&hotkey,
120+
old_coldkey,
121+
new_coldkey,
188122
);
189-
// Remove the value from the old account.
190-
Alpha::<T>::remove((&hotkey, old_coldkey, netuid));
191123

192-
if new_alpha.saturating_add(old_alpha) > U64F64::from(0u64) {
193-
Self::transfer_root_claimed_for_new_keys(
194-
netuid,
195-
&hotkey,
196-
&hotkey,
197-
old_coldkey,
198-
new_coldkey,
199-
);
200-
201-
if netuid == NetUid::ROOT {
202-
// Register new coldkey with root stake
203-
Self::maybe_add_coldkey_index(new_coldkey);
204-
}
124+
if netuid == NetUid::ROOT {
125+
// Register new coldkey with root stake
126+
Self::maybe_add_coldkey_index(new_coldkey);
205127
}
206128
}
207-
// Add the weight for the read and write.
208-
weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2));
209129
}
130+
}
210131

211-
// 4. Swap TotalColdkeyAlpha (DEPRECATED)
212-
// for netuid in Self::get_all_subnet_netuids() {
213-
// let old_alpha_stake: u64 = TotalColdkeyAlpha::<T>::get(old_coldkey, netuid);
214-
// let new_alpha_stake: u64 = TotalColdkeyAlpha::<T>::get(new_coldkey, netuid);
215-
// TotalColdkeyAlpha::<T>::insert(
216-
// new_coldkey,
217-
// netuid,
218-
// new_alpha_stake.saturating_add(old_alpha_stake),
219-
// );
220-
// TotalColdkeyAlpha::<T>::remove(old_coldkey, netuid);
221-
// }
222-
// weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2));
223-
224-
// 5. Swap StakingHotkeys.
225-
// StakingHotkeys: MAP ( coldkey ) --> Vec<hotkeys> | Hotkeys staking for the coldkey.
132+
/// Transfer staking hotkeys from the old coldkey to the new coldkey.
133+
fn transfer_staking_hotkeys(old_coldkey: &T::AccountId, new_coldkey: &T::AccountId) {
226134
let old_staking_hotkeys: Vec<T::AccountId> = StakingHotkeys::<T>::get(old_coldkey);
227135
let mut new_staking_hotkeys: Vec<T::AccountId> = StakingHotkeys::<T>::get(new_coldkey);
228136
for hotkey in old_staking_hotkeys {
@@ -231,13 +139,13 @@ impl<T: Config> Pallet<T> {
231139
new_staking_hotkeys.push(hotkey);
232140
}
233141
}
142+
234143
StakingHotkeys::<T>::remove(old_coldkey);
235144
StakingHotkeys::<T>::insert(new_coldkey, new_staking_hotkeys);
236-
weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2));
145+
}
237146

238-
// 6. Swap hotkey owners.
239-
// Owner: MAP ( hotkey ) --> coldkey | Owner of the hotkey.
240-
// OwnedHotkeys: MAP ( coldkey ) --> Vec<hotkeys> | Hotkeys owned by the coldkey.
147+
/// Transfer the ownership of the hotkeys owned by the old coldkey to the new coldkey.
148+
fn transfer_hotkeys_ownership(old_coldkey: &T::AccountId, new_coldkey: &T::AccountId) {
241149
let old_owned_hotkeys: Vec<T::AccountId> = OwnedHotkeys::<T>::get(old_coldkey);
242150
let mut new_owned_hotkeys: Vec<T::AccountId> = OwnedHotkeys::<T>::get(new_coldkey);
243151
for owned_hotkey in old_owned_hotkeys.iter() {
@@ -252,19 +160,5 @@ impl<T: Config> Pallet<T> {
252160
}
253161
OwnedHotkeys::<T>::remove(old_coldkey);
254162
OwnedHotkeys::<T>::insert(new_coldkey, new_owned_hotkeys);
255-
weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2));
256-
257-
// 7. Transfer remaining balance.
258-
// Balance: MAP ( coldkey ) --> u64 | Balance of the coldkey.
259-
// Transfer any remaining balance from old_coldkey to new_coldkey
260-
let remaining_balance = Self::get_coldkey_balance(old_coldkey);
261-
if remaining_balance > 0 {
262-
Self::kill_coldkey_account(old_coldkey, remaining_balance)?;
263-
Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance);
264-
}
265-
weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2));
266-
267-
// Return ok.
268-
Ok(())
269163
}
270164
}

pallets/subtensor/src/tests/claim_root.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,12 +1184,10 @@ fn test_claim_root_with_swap_coldkey() {
11841184
);
11851185

11861186
// Swap coldkey
1187-
let mut weight = Weight::zero();
11881187

11891188
assert_ok!(SubtensorModule::perform_swap_coldkey(
11901189
&coldkey,
11911190
&new_coldkey,
1192-
&mut weight
11931191
));
11941192

11951193
// Check swapped keys claimed values

0 commit comments

Comments
 (0)