Skip to content

Commit b2b9636

Browse files
committed
refacto to handle subsubnet when trimming uids
1 parent a027ba7 commit b2b9636

File tree

1 file changed

+94
-68
lines changed
  • pallets/subtensor/src/subnets

1 file changed

+94
-68
lines changed

pallets/subtensor/src/subnets/uids.rs

Lines changed: 94 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ impl<T: Config> Pallet<T> {
148148

149149
MaxAllowedUids::<T>::insert(netuid, max_n);
150150

151-
let owner = SubnetOwner::<T>::get(netuid);
152-
let owner_uids = BTreeSet::from_iter(Self::get_immune_owner_uids(netuid, &owner));
153151
let current_n = Self::get_subnetwork_n(netuid);
154-
155152
if current_n > max_n {
153+
let owner = SubnetOwner::<T>::get(netuid);
154+
let owner_uids = BTreeSet::from_iter(Self::get_immune_owner_uids(netuid, &owner));
155+
156156
// Count the number of immune UIDs
157157
let mut immune_count: u16 = 0;
158158
for uid in 0..current_n {
@@ -167,7 +167,8 @@ impl<T: Config> Pallet<T> {
167167
immune_percentage < T::MaxImmuneUidsPercentage::get(),
168168
Error::<T>::InvalidValue
169169
);
170-
170+
171+
171172
// Get all emissions with their UIDs and sort by emission (descending)
172173
// This ensures we keep the highest emitters and remove the lowest ones
173174
let mut emissions = Emission::<T>::get(netuid)
@@ -176,9 +177,9 @@ impl<T: Config> Pallet<T> {
176177
.collect::<Vec<_>>();
177178
emissions.sort_by_key(|(_, emission)| cmp::Reverse(*emission));
178179

179-
// Remove uids from the end (lowest emitters) until we reach the new maximum
180180
let mut removed_uids = BTreeSet::new();
181181
let mut uids_left_to_process = current_n;
182+
let subsubnets_count = SubsubnetCountCurrent::<T>::get(netuid).into();
182183

183184
// Iterate from the end (lowest emitters) to the beginning
184185
for i in (0..current_n).rev() {
@@ -187,15 +188,17 @@ impl<T: Config> Pallet<T> {
187188
}
188189

189190
if let Some((uid, _)) = emissions.get(i as usize).cloned() {
191+
let neuron_uid = uid as u16;
192+
190193
// Skip subnet owner's or temporally immune uids
191-
if owner_uids.contains(&(uid as u16))
192-
|| Self::get_neuron_is_immune(netuid, uid as u16)
194+
if owner_uids.contains(&neuron_uid)
195+
|| Self::get_neuron_is_immune(netuid, neuron_uid)
193196
{
194197
continue;
195198
}
196199

197200
// Remove hotkey related storage items if hotkey exists
198-
if let Ok(hotkey) = Keys::<T>::try_get(netuid, uid as u16) {
201+
if let Ok(hotkey) = Keys::<T>::try_get(netuid, neuron_uid) {
199202
Uids::<T>::remove(netuid, &hotkey);
200203
IsNetworkMember::<T>::remove(&hotkey, netuid);
201204
LastHotkeyEmissionOnNetuid::<T>::remove(&hotkey, netuid);
@@ -208,10 +211,13 @@ impl<T: Config> Pallet<T> {
208211

209212
// Remove all storage items associated with this uid
210213
#[allow(unknown_lints)]
211-
Keys::<T>::remove(netuid, uid as u16);
212-
BlockAtRegistration::<T>::remove(netuid, uid as u16);
213-
Weights::<T>::remove(netuid, uid as u16);
214-
Bonds::<T>::remove(netuid, uid as u16);
214+
Keys::<T>::remove(netuid, neuron_uid);
215+
BlockAtRegistration::<T>::remove(netuid, neuron_uid);
216+
for subid in 0..subsubnets_count {
217+
let netuid_index = Self::get_subsubnet_storage_index(netuid, subid.into());
218+
Weights::<T>::remove(netuid_index, neuron_uid);
219+
Bonds::<T>::remove(netuid_index, neuron_uid);
220+
}
215221

216222
// Remove from emissions array and track as removed
217223
emissions.remove(i.into());
@@ -233,42 +239,36 @@ impl<T: Config> Pallet<T> {
233239
let trust = Trust::<T>::get(netuid);
234240
let active = Active::<T>::get(netuid);
235241
let consensus = Consensus::<T>::get(netuid);
236-
let incentive = Incentive::<T>::get(netuid);
237242
let dividends = Dividends::<T>::get(netuid);
238-
let lastupdate = LastUpdate::<T>::get(netuid);
239243
let pruning_scores = PruningScores::<T>::get(netuid);
240244
let vtrust = ValidatorTrust::<T>::get(netuid);
241245
let vpermit = ValidatorPermit::<T>::get(netuid);
242246
let stake_weight = StakeWeight::<T>::get(netuid);
243247

244248
// Create trimmed arrays by extracting values for kept uids only
245249
// Pre-allocate vectors with exact capacity for efficiency
246-
let mut trimmed_ranks = Vec::with_capacity(trimmed_uids.len());
247-
let mut trimmed_trust = Vec::with_capacity(trimmed_uids.len());
248-
let mut trimmed_active = Vec::with_capacity(trimmed_uids.len());
249-
let mut trimmed_consensus = Vec::with_capacity(trimmed_uids.len());
250-
let mut trimmed_incentive = Vec::with_capacity(trimmed_uids.len());
251-
let mut trimmed_dividends = Vec::with_capacity(trimmed_uids.len());
252-
let mut trimmed_lastupdate = Vec::with_capacity(trimmed_uids.len());
253-
let mut trimmed_pruning_scores = Vec::with_capacity(trimmed_uids.len());
254-
let mut trimmed_vtrust = Vec::with_capacity(trimmed_uids.len());
255-
let mut trimmed_vpermit = Vec::with_capacity(trimmed_uids.len());
256-
let mut trimmed_stake_weight = Vec::with_capacity(trimmed_uids.len());
250+
let len = trimmed_uids.len();
251+
let mut trimmed_ranks = Vec::with_capacity(len);
252+
let mut trimmed_trust = Vec::with_capacity(len);
253+
let mut trimmed_active = Vec::with_capacity(len);
254+
let mut trimmed_consensus = Vec::with_capacity(len);
255+
let mut trimmed_dividends = Vec::with_capacity(len);
256+
let mut trimmed_pruning_scores = Vec::with_capacity(len);
257+
let mut trimmed_vtrust = Vec::with_capacity(len);
258+
let mut trimmed_vpermit = Vec::with_capacity(len);
259+
let mut trimmed_stake_weight = Vec::with_capacity(len);
257260

258261
// Single iteration to extract values for all kept uids
259-
for &old_uid in &trimmed_uids {
260-
trimmed_ranks.push(ranks.get(old_uid).cloned().unwrap_or_default());
261-
trimmed_trust.push(trust.get(old_uid).cloned().unwrap_or_default());
262-
trimmed_active.push(active.get(old_uid).cloned().unwrap_or_default());
263-
trimmed_consensus.push(consensus.get(old_uid).cloned().unwrap_or_default());
264-
trimmed_incentive.push(incentive.get(old_uid).cloned().unwrap_or_default());
265-
trimmed_dividends.push(dividends.get(old_uid).cloned().unwrap_or_default());
266-
trimmed_lastupdate.push(lastupdate.get(old_uid).cloned().unwrap_or_default());
267-
trimmed_pruning_scores
268-
.push(pruning_scores.get(old_uid).cloned().unwrap_or_default());
269-
trimmed_vtrust.push(vtrust.get(old_uid).cloned().unwrap_or_default());
270-
trimmed_vpermit.push(vpermit.get(old_uid).cloned().unwrap_or_default());
271-
trimmed_stake_weight.push(stake_weight.get(old_uid).cloned().unwrap_or_default());
262+
for &uid in &trimmed_uids {
263+
trimmed_ranks.push(ranks.get(uid).cloned().unwrap_or_default());
264+
trimmed_trust.push(trust.get(uid).cloned().unwrap_or_default());
265+
trimmed_active.push(active.get(uid).cloned().unwrap_or_default());
266+
trimmed_consensus.push(consensus.get(uid).cloned().unwrap_or_default());
267+
trimmed_dividends.push(dividends.get(uid).cloned().unwrap_or_default());
268+
trimmed_pruning_scores.push(pruning_scores.get(uid).cloned().unwrap_or_default());
269+
trimmed_vtrust.push(vtrust.get(uid).cloned().unwrap_or_default());
270+
trimmed_vpermit.push(vpermit.get(uid).cloned().unwrap_or_default());
271+
trimmed_stake_weight.push(stake_weight.get(uid).cloned().unwrap_or_default());
272272
}
273273

274274
// Update storage with trimmed arrays
@@ -277,14 +277,29 @@ impl<T: Config> Pallet<T> {
277277
Trust::<T>::insert(netuid, trimmed_trust);
278278
Active::<T>::insert(netuid, trimmed_active);
279279
Consensus::<T>::insert(netuid, trimmed_consensus);
280-
Incentive::<T>::insert(netuid, trimmed_incentive);
281280
Dividends::<T>::insert(netuid, trimmed_dividends);
282-
LastUpdate::<T>::insert(netuid, trimmed_lastupdate);
283281
PruningScores::<T>::insert(netuid, trimmed_pruning_scores);
284282
ValidatorTrust::<T>::insert(netuid, trimmed_vtrust);
285283
ValidatorPermit::<T>::insert(netuid, trimmed_vpermit);
286284
StakeWeight::<T>::insert(netuid, trimmed_stake_weight);
287285

286+
// Update incentives/lastupdates for subsubnets
287+
for subid in 0..subsubnets_count {
288+
let netuid_index = Self::get_subsubnet_storage_index(netuid, subid.into());
289+
let incentive = Incentive::<T>::get(netuid_index);
290+
let lastupdate = LastUpdate::<T>::get(netuid_index);
291+
let mut trimmed_incentive = Vec::with_capacity(trimmed_uids.len());
292+
let mut trimmed_lastupdate = Vec::with_capacity(trimmed_uids.len());
293+
294+
for uid in &trimmed_uids {
295+
trimmed_incentive.push(incentive.get(*uid).cloned().unwrap_or_default());
296+
trimmed_lastupdate.push(lastupdate.get(*uid).cloned().unwrap_or_default());
297+
}
298+
299+
Incentive::<T>::insert(netuid_index, trimmed_incentive);
300+
LastUpdate::<T>::insert(netuid_index, trimmed_lastupdate);
301+
}
302+
288303
// Create mapping from old uid to new compressed uid
289304
// This is needed to update connections (weights and bonds) with correct uid references
290305
let old_to_new_uid: BTreeMap<usize, usize> = trimmed_uids
@@ -299,35 +314,46 @@ impl<T: Config> Pallet<T> {
299314
// 2. Update all connections to reference the new compressed uids
300315
// 3. Clear the connections to the trimmed uids
301316
for (old_uid, new_uid) in &old_to_new_uid {
302-
// Swap uid specific storage items to new compressed positions
303-
Keys::<T>::swap(netuid, *old_uid as u16, netuid, *new_uid as u16);
304-
BlockAtRegistration::<T>::swap(netuid, *old_uid as u16, netuid, *new_uid as u16);
305-
306-
// Swap to new position and remap all target uids
307-
Weights::<T>::swap(netuid, *old_uid as u16, netuid, *new_uid as u16);
308-
Weights::<T>::mutate(netuid, *new_uid as u16, |weights| {
309-
weights.retain_mut(|(target_uid, _weight)| {
310-
if let Some(new_target_uid) = old_to_new_uid.get(&(*target_uid as usize)) {
311-
*target_uid = *new_target_uid as u16;
312-
true
313-
} else {
314-
false
315-
}
316-
})
317-
});
317+
let old_neuron_uid = *old_uid as u16;
318+
let new_neuron_uid = *new_uid as u16;
318319

319-
// Swap to new position and remap all target uids
320-
Bonds::<T>::swap(netuid, *old_uid as u16, netuid, *new_uid as u16);
321-
Bonds::<T>::mutate(netuid, *new_uid as u16, |bonds| {
322-
bonds.retain_mut(|(target_uid, _bond)| {
323-
if let Some(new_target_uid) = old_to_new_uid.get(&(*target_uid as usize)) {
324-
*target_uid = *new_target_uid as u16;
325-
true
326-
} else {
327-
false
328-
}
329-
})
330-
});
320+
// Swap uid specific storage items to new compressed positions
321+
Keys::<T>::swap(netuid, old_neuron_uid, netuid, new_neuron_uid);
322+
BlockAtRegistration::<T>::swap(netuid, old_neuron_uid, netuid, new_neuron_uid);
323+
324+
for subid in 0..subsubnets_count {
325+
let netuid_index = Self::get_subsubnet_storage_index(netuid, subid.into());
326+
327+
// Swap to new position and remap all target uids
328+
Weights::<T>::swap(netuid_index, old_neuron_uid, netuid_index, new_neuron_uid);
329+
Weights::<T>::mutate(netuid_index, new_neuron_uid, |weights| {
330+
weights.retain_mut(|(target_uid, _weight)| {
331+
if let Some(new_target_uid) =
332+
old_to_new_uid.get(&(*target_uid as usize))
333+
{
334+
*target_uid = *new_target_uid as u16;
335+
true
336+
} else {
337+
false
338+
}
339+
})
340+
});
341+
342+
// Swap to new position and remap all target uids
343+
Bonds::<T>::swap(netuid_index, old_neuron_uid, netuid_index, new_neuron_uid);
344+
Bonds::<T>::mutate(netuid_index, new_neuron_uid, |bonds| {
345+
bonds.retain_mut(|(target_uid, _bond)| {
346+
if let Some(new_target_uid) =
347+
old_to_new_uid.get(&(*target_uid as usize))
348+
{
349+
*target_uid = *new_target_uid as u16;
350+
true
351+
} else {
352+
false
353+
}
354+
})
355+
});
356+
}
331357
}
332358

333359
// Update the subnet's uid count to reflect the new maximum

0 commit comments

Comments
 (0)