Skip to content

Commit

Permalink
Merge branch 'feat/no-owner-dereg' into nonclaim
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnReedV committed Feb 6, 2025
2 parents ae25f59 + bbbfb3a commit 33a842d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 0 deletions.
8 changes: 8 additions & 0 deletions pallets/subtensor/src/subnets/registration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,14 @@ impl<T: Config> Pallet<T> {
}

for neuron_uid in 0..neurons_n {
// Do not deregister the owner
if let Ok(hotkey) = Self::get_hotkey_for_net_and_uid(netuid, neuron_uid) {
let coldkey = Self::get_owning_coldkey_for_hotkey(&hotkey);
if Self::get_subnet_owner(netuid) == coldkey {
continue;
}
}

let pruning_score: u16 = Self::get_pruning_score_for_uid(netuid, neuron_uid);
let block_at_registration: u64 =
Self::get_neuron_block_at_registration(netuid, neuron_uid);
Expand Down
14 changes: 14 additions & 0 deletions pallets/subtensor/src/subnets/uids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ impl<T: Config> Pallet<T> {
// 1. Get the old hotkey under this position.
let old_hotkey: T::AccountId = Keys::<T>::get(netuid, uid_to_replace);

// Do not deregister the owner
let coldkey = Self::get_owning_coldkey_for_hotkey(&old_hotkey);
if Self::get_subnet_owner(netuid) == coldkey {
log::warn!(
"replace_neuron: Skipped replacement because neuron belongs to the subnet owner. \
netuid: {:?}, uid_to_replace: {:?}, new_hotkey: {:?}, owner_coldkey: {:?}",
netuid,
uid_to_replace,
new_hotkey,
coldkey
);
return;
}

// 2. Remove previous set memberships.
Uids::<T>::remove(netuid, old_hotkey.clone());
IsNetworkMember::<T>::remove(old_hotkey.clone(), netuid);
Expand Down
4 changes: 4 additions & 0 deletions pallets/subtensor/src/tests/difficulty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ fn test_registration_difficulty_adjustment() {
let tempo: u16 = 1;
let modality: u16 = 1;
add_network(netuid, tempo, modality);

// owners are not deregistered
crate::SubnetOwner::<Test>::insert(netuid, U256::from(99999));

SubtensorModule::set_min_difficulty(netuid, 10000);
assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), 10000); // Check initial difficulty.
assert_eq!(SubtensorModule::get_last_adjustment_block(netuid), 0); // Last adjustment block starts at 0.
Expand Down
6 changes: 6 additions & 0 deletions pallets/subtensor/src/tests/registration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,12 @@ fn test_full_pass_through() {
add_network(netuid1, tempo1, 0);
add_network(netuid2, tempo2, 0);

// owners are not deregisterd
let dummy_owner = U256::from(99999);
crate::SubnetOwner::<Test>::insert(netuid0, dummy_owner);
crate::SubnetOwner::<Test>::insert(netuid1, dummy_owner);
crate::SubnetOwner::<Test>::insert(netuid2, dummy_owner);

// Check their tempo.
assert_eq!(SubtensorModule::get_tempo(netuid0), tempo0);
assert_eq!(SubtensorModule::get_tempo(netuid1), tempo1);
Expand Down
85 changes: 85 additions & 0 deletions pallets/subtensor/src/tests/uids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,88 @@ fn test_neuron_certificate() {
assert_err!(NeuronCertificate::try_from(data), ());
});
}

#[test]
fn test_replace_neuron_subnet_owner_not_replaced() {
new_test_ext(1).execute_with(|| {
let owner_hotkey = U256::from(100);
let owner_coldkey = U256::from(999);
let new_hotkey_account_id = U256::from(2);

let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey);
let neuron_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &owner_hotkey)
.expect("Owner neuron should be registered by add_dynamic_network");

let current_block = SubtensorModule::get_current_block_as_u64();
SubtensorModule::replace_neuron(netuid, neuron_uid, &new_hotkey_account_id, current_block);

let still_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &owner_hotkey);
assert_ok!(still_uid);
assert_eq!(
still_uid.unwrap(),
neuron_uid,
"UID should remain unchanged for subnet owner"
);

let new_key_uid =
SubtensorModule::get_uid_for_net_and_hotkey(netuid, &new_hotkey_account_id);
assert_err!(new_key_uid, Error::<Test>::HotKeyNotRegisteredInSubNet,);
});
}

#[test]
fn test_get_neuron_to_prune_owner_not_pruned() {
new_test_ext(1).execute_with(|| {
let owner_hotkey = U256::from(123);
let owner_coldkey = U256::from(999);

let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey);

SubtensorModule::set_max_registrations_per_block(netuid, 100);
SubtensorModule::set_target_registrations_per_interval(netuid, 100);
SubnetOwner::<Test>::insert(netuid, owner_coldkey);

let owner_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &owner_hotkey)
.expect("Owner neuron should already be registered by add_dynamic_network");

let additional_hotkey_1 = U256::from(1000);
let additional_coldkey_1 = U256::from(2000);

let additional_hotkey_2 = U256::from(1001);
let additional_coldkey_2 = U256::from(2001);

register_ok_neuron(netuid, additional_hotkey_1, additional_coldkey_1, 0);
let uid_1 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &additional_hotkey_1)
.expect("Should be registered");

register_ok_neuron(netuid, additional_hotkey_2, additional_coldkey_2, 1);
let uid_2 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &additional_hotkey_2)
.expect("Should be registered");

SubtensorModule::set_pruning_score_for_uid(netuid, owner_uid, 0);
SubtensorModule::set_pruning_score_for_uid(netuid, uid_1, 1);
SubtensorModule::set_pruning_score_for_uid(netuid, uid_2, 2);

let pruned_uid = SubtensorModule::get_neuron_to_prune(netuid);

// - The pruned UID must be `uid_1` (score=1).
// - The owner's UID remains unpruned.
assert_eq!(
pruned_uid, uid_1,
"Should prune the neuron with pruning score=1, not the owner (score=0)."
);

let pruned_score = SubtensorModule::get_pruning_score_for_uid(netuid, uid_1);
assert_eq!(
pruned_score,
u16::MAX,
"Pruned neuron's score should be set to u16::MAX"
);

let owner_score = SubtensorModule::get_pruning_score_for_uid(netuid, owner_uid);
assert_eq!(
owner_score, 0,
"Owner's pruning score remains 0, indicating it was skipped"
);
});
}

0 comments on commit 33a842d

Please sign in to comment.