diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index b590781f5..351bc39bf 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1001,19 +1001,18 @@ pub mod pallet { pub(super) type Rank = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> trust - pub(super) type Trust = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Trust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> consensus - pub(super) type Consensus = + pub type Consensus = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> incentive - pub(super) type Incentive = + pub type Incentive = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> dividends - pub(super) type Dividends = + pub type Dividends = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> emission - pub(super) type Emission = + pub type Emission = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> last_update pub(super) type LastUpdate = diff --git a/pallets/subtensor/src/uids.rs b/pallets/subtensor/src/uids.rs index 4ae2c24de..8632ad4d3 100644 --- a/pallets/subtensor/src/uids.rs +++ b/pallets/subtensor/src/uids.rs @@ -9,6 +9,28 @@ impl Pallet { SubnetworkN::::get(netuid) } + /// Returns a callback that sets the element at the given position to zero, doing nothing if the + /// position is out of bounds + fn clear_element_at(position: u16) -> impl Fn(&mut Vec) + where + N: From, + { + move |vec: &mut Vec| { + if vec.len() > position as usize { + vec[position as usize] = N::from(0); + }; + } + } + + /// Resets the trust, emission, consensus, incentive, dividends of the neuron to default + pub fn clear_neuron(netuid: u16, neuron_uid: u16) { + Emission::::mutate(netuid, Self::clear_element_at(neuron_uid)); + Trust::::mutate(netuid, Self::clear_element_at(neuron_uid)); + Consensus::::mutate(netuid, Self::clear_element_at(neuron_uid)); + Incentive::::mutate(netuid, Self::clear_element_at(neuron_uid)); + Dividends::::mutate(netuid, Self::clear_element_at(neuron_uid)); + } + /// Replace the neuron under this uid. pub fn replace_neuron( netuid: u16, @@ -45,6 +67,12 @@ impl Pallet { Uids::::insert(netuid, new_hotkey.clone(), uid_to_replace); // Make uid - hotkey association. BlockAtRegistration::::insert(netuid, uid_to_replace, block_number); // Fill block at registration. IsNetworkMember::::insert(new_hotkey.clone(), netuid, true); // Fill network is member. + + // 4. Reset new neuron's values. + Self::clear_neuron(netuid, uid_to_replace); + + // 4a. reset axon info for the new uid. + Axons::::remove(netuid, old_hotkey); } /// Appends the uid to the network. diff --git a/pallets/subtensor/tests/uids.rs b/pallets/subtensor/tests/uids.rs index b8a969943..b0049216c 100644 --- a/pallets/subtensor/tests/uids.rs +++ b/pallets/subtensor/tests/uids.rs @@ -1,6 +1,7 @@ use crate::mock::*; use frame_support::assert_ok; use frame_system::Config; +use pallet_subtensor::*; use sp_core::U256; mod mock; @@ -48,14 +49,37 @@ fn test_replace_neuron() { // Get UID let neuron_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id); assert_ok!(neuron_uid); + let neuron_uid = neuron_uid.unwrap(); + + // set non-default values + Trust::::mutate(netuid, |v| v[neuron_uid as usize] = 5u16); + Emission::::mutate(netuid, |v| v[neuron_uid as usize] = 5u64); + Consensus::::mutate(netuid, |v| v[neuron_uid as usize] = 5u16); + Incentive::::mutate(netuid, |v| v[neuron_uid as usize] = 5u16); + Dividends::::mutate(netuid, |v| v[neuron_uid as usize] = 5u16); + + // serve axon mock address + let ip: u128 = 1676056785; + let port: u16 = 9999; + let ip_type: u8 = 4; + let hotkey = SubtensorModule::get_hotkey_for_net_and_uid(netuid, neuron_uid).unwrap(); + assert!(SubtensorModule::serve_axon( + <::RuntimeOrigin>::signed(hotkey_account_id), + netuid, + 0, + ip, + port, + ip_type, + 0, + 0, + 0 + ) + .is_ok()); // Replace the neuron. - SubtensorModule::replace_neuron( - netuid, - neuron_uid.unwrap(), - &new_hotkey_account_id, - block_number, - ); + SubtensorModule::replace_neuron(netuid, neuron_uid, &new_hotkey_account_id, block_number); + + assert!(!SubtensorModule::has_axon_info(netuid, &hotkey)); // Check old hotkey is not registered on any network. assert!(SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id).is_err()); @@ -63,7 +87,7 @@ fn test_replace_neuron() { &hotkey_account_id )); - let curr_hotkey = SubtensorModule::get_hotkey_for_net_and_uid(netuid, neuron_uid.unwrap()); + let curr_hotkey = SubtensorModule::get_hotkey_for_net_and_uid(netuid, neuron_uid); assert_ok!(curr_hotkey); assert_ne!(curr_hotkey.unwrap(), hotkey_account_id); @@ -75,6 +99,33 @@ fn test_replace_neuron() { &new_hotkey_account_id )); assert_eq!(curr_hotkey.unwrap(), new_hotkey_account_id); + + // Check trust, emission, consensus, incentive, dividends have been reset to 0. + assert_eq!(SubtensorModule::get_trust_for_uid(netuid, neuron_uid), 0); + assert_eq!(SubtensorModule::get_emission_for_uid(netuid, neuron_uid), 0); + assert_eq!( + SubtensorModule::get_consensus_for_uid(netuid, neuron_uid), + 0 + ); + assert_eq!( + SubtensorModule::get_incentive_for_uid(netuid, neuron_uid), + 0 + ); + assert_eq!( + SubtensorModule::get_dividends_for_uid(netuid, neuron_uid), + 0 + ); + + assert!(!SubtensorModule::has_axon_info( + netuid, + &new_hotkey_account_id + )); + + // Check axon info is reset. + let axon_info = SubtensorModule::get_axon_info(netuid, &curr_hotkey.unwrap()); + assert_eq!(axon_info.ip, 0); + assert_eq!(axon_info.port, 0); + assert_eq!(axon_info.ip_type, 0); }); }