Skip to content

Commit dafc7a2

Browse files
committed
Merge branch 'nonclaim' of github.com:opentensor/subtensor into nonclaim
2 parents 841c913 + 33a842d commit dafc7a2

File tree

5 files changed

+117
-0
lines changed

5 files changed

+117
-0
lines changed

pallets/subtensor/src/subnets/registration.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,14 @@ impl<T: Config> Pallet<T> {
425425
}
426426

427427
for neuron_uid in 0..neurons_n {
428+
// Do not deregister the owner
429+
if let Ok(hotkey) = Self::get_hotkey_for_net_and_uid(netuid, neuron_uid) {
430+
let coldkey = Self::get_owning_coldkey_for_hotkey(&hotkey);
431+
if Self::get_subnet_owner(netuid) == coldkey {
432+
continue;
433+
}
434+
}
435+
428436
let pruning_score: u16 = Self::get_pruning_score_for_uid(netuid, neuron_uid);
429437
let block_at_registration: u64 =
430438
Self::get_neuron_block_at_registration(netuid, neuron_uid);

pallets/subtensor/src/subnets/uids.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ impl<T: Config> Pallet<T> {
4242
// 1. Get the old hotkey under this position.
4343
let old_hotkey: T::AccountId = Keys::<T>::get(netuid, uid_to_replace);
4444

45+
// Do not deregister the owner
46+
let coldkey = Self::get_owning_coldkey_for_hotkey(&old_hotkey);
47+
if Self::get_subnet_owner(netuid) == coldkey {
48+
log::warn!(
49+
"replace_neuron: Skipped replacement because neuron belongs to the subnet owner. \
50+
netuid: {:?}, uid_to_replace: {:?}, new_hotkey: {:?}, owner_coldkey: {:?}",
51+
netuid,
52+
uid_to_replace,
53+
new_hotkey,
54+
coldkey
55+
);
56+
return;
57+
}
58+
4559
// 2. Remove previous set memberships.
4660
Uids::<T>::remove(netuid, old_hotkey.clone());
4761
IsNetworkMember::<T>::remove(old_hotkey.clone(), netuid);

pallets/subtensor/src/tests/difficulty.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ fn test_registration_difficulty_adjustment() {
1313
let tempo: u16 = 1;
1414
let modality: u16 = 1;
1515
add_network(netuid, tempo, modality);
16+
17+
// owners are not deregistered
18+
crate::SubnetOwner::<Test>::insert(netuid, U256::from(99999));
19+
1620
SubtensorModule::set_min_difficulty(netuid, 10000);
1721
assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), 10000); // Check initial difficulty.
1822
assert_eq!(SubtensorModule::get_last_adjustment_block(netuid), 0); // Last adjustment block starts at 0.

pallets/subtensor/src/tests/registration.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,12 @@ fn test_full_pass_through() {
15601560
add_network(netuid1, tempo1, 0);
15611561
add_network(netuid2, tempo2, 0);
15621562

1563+
// owners are not deregisterd
1564+
let dummy_owner = U256::from(99999);
1565+
crate::SubnetOwner::<Test>::insert(netuid0, dummy_owner);
1566+
crate::SubnetOwner::<Test>::insert(netuid1, dummy_owner);
1567+
crate::SubnetOwner::<Test>::insert(netuid2, dummy_owner);
1568+
15631569
// Check their tempo.
15641570
assert_eq!(SubtensorModule::get_tempo(netuid0), tempo0);
15651571
assert_eq!(SubtensorModule::get_tempo(netuid1), tempo1);

pallets/subtensor/src/tests/uids.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,88 @@ fn test_neuron_certificate() {
250250
assert_err!(NeuronCertificate::try_from(data), ());
251251
});
252252
}
253+
254+
#[test]
255+
fn test_replace_neuron_subnet_owner_not_replaced() {
256+
new_test_ext(1).execute_with(|| {
257+
let owner_hotkey = U256::from(100);
258+
let owner_coldkey = U256::from(999);
259+
let new_hotkey_account_id = U256::from(2);
260+
261+
let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey);
262+
let neuron_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &owner_hotkey)
263+
.expect("Owner neuron should be registered by add_dynamic_network");
264+
265+
let current_block = SubtensorModule::get_current_block_as_u64();
266+
SubtensorModule::replace_neuron(netuid, neuron_uid, &new_hotkey_account_id, current_block);
267+
268+
let still_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &owner_hotkey);
269+
assert_ok!(still_uid);
270+
assert_eq!(
271+
still_uid.unwrap(),
272+
neuron_uid,
273+
"UID should remain unchanged for subnet owner"
274+
);
275+
276+
let new_key_uid =
277+
SubtensorModule::get_uid_for_net_and_hotkey(netuid, &new_hotkey_account_id);
278+
assert_err!(new_key_uid, Error::<Test>::HotKeyNotRegisteredInSubNet,);
279+
});
280+
}
281+
282+
#[test]
283+
fn test_get_neuron_to_prune_owner_not_pruned() {
284+
new_test_ext(1).execute_with(|| {
285+
let owner_hotkey = U256::from(123);
286+
let owner_coldkey = U256::from(999);
287+
288+
let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey);
289+
290+
SubtensorModule::set_max_registrations_per_block(netuid, 100);
291+
SubtensorModule::set_target_registrations_per_interval(netuid, 100);
292+
SubnetOwner::<Test>::insert(netuid, owner_coldkey);
293+
294+
let owner_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &owner_hotkey)
295+
.expect("Owner neuron should already be registered by add_dynamic_network");
296+
297+
let additional_hotkey_1 = U256::from(1000);
298+
let additional_coldkey_1 = U256::from(2000);
299+
300+
let additional_hotkey_2 = U256::from(1001);
301+
let additional_coldkey_2 = U256::from(2001);
302+
303+
register_ok_neuron(netuid, additional_hotkey_1, additional_coldkey_1, 0);
304+
let uid_1 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &additional_hotkey_1)
305+
.expect("Should be registered");
306+
307+
register_ok_neuron(netuid, additional_hotkey_2, additional_coldkey_2, 1);
308+
let uid_2 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &additional_hotkey_2)
309+
.expect("Should be registered");
310+
311+
SubtensorModule::set_pruning_score_for_uid(netuid, owner_uid, 0);
312+
SubtensorModule::set_pruning_score_for_uid(netuid, uid_1, 1);
313+
SubtensorModule::set_pruning_score_for_uid(netuid, uid_2, 2);
314+
315+
let pruned_uid = SubtensorModule::get_neuron_to_prune(netuid);
316+
317+
// - The pruned UID must be `uid_1` (score=1).
318+
// - The owner's UID remains unpruned.
319+
assert_eq!(
320+
pruned_uid, uid_1,
321+
"Should prune the neuron with pruning score=1, not the owner (score=0)."
322+
);
323+
324+
let pruned_score = SubtensorModule::get_pruning_score_for_uid(netuid, uid_1);
325+
assert_eq!(
326+
pruned_score,
327+
u16::MAX,
328+
"Pruned neuron's score should be set to u16::MAX"
329+
);
330+
331+
let owner_score = SubtensorModule::get_pruning_score_for_uid(netuid, owner_uid);
332+
assert_eq!(
333+
owner_score, 0,
334+
"Owner's pruning score remains 0, indicating it was skipped"
335+
);
336+
});
337+
}

0 commit comments

Comments
 (0)