diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index 11f59602d..f48cd3b50 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -9,6 +9,23 @@ impl Pallet { SubnetworkN::::get(netuid) } + /// Sets value for the element at the given position if it exists. + pub fn set_element_at(vec: &mut [N], position: usize, value: N) { + if let Some(element) = vec.get_mut(position) { + *element = value; + } + } + + /// Resets the trust, emission, consensus, incentive, dividends of the neuron to default + pub fn clear_neuron(netuid: u16, neuron_uid: u16) { + let neuron_index: usize = neuron_uid.into(); + Emission::::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0)); + Trust::::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0)); + Consensus::::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0)); + Incentive::::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0)); + Dividends::::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0)); + } + /// Replace the neuron under this uid. pub fn replace_neuron( netuid: u16, @@ -48,6 +65,12 @@ impl Pallet { // 4. Clear neuron certificates NeuronCertificates::::remove(netuid, old_hotkey.clone()); + + // 5. Reset new neuron's values. + Self::clear_neuron(netuid, uid_to_replace); + + // 5a. 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 6b4c00328..e56d16020 100644 --- a/pallets/subtensor/tests/uids.rs +++ b/pallets/subtensor/tests/uids.rs @@ -52,17 +52,50 @@ 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| { + SubtensorModule::set_element_at(v, neuron_uid as usize, 5u16) + }); + Emission::::mutate(netuid, |v| { + SubtensorModule::set_element_at(v, neuron_uid as usize, 5u64) + }); + Consensus::::mutate(netuid, |v| { + SubtensorModule::set_element_at(v, neuron_uid as usize, 5u16) + }); + Incentive::::mutate(netuid, |v| { + SubtensorModule::set_element_at(v, neuron_uid as usize, 5u16) + }); + Dividends::::mutate(netuid, |v| { + SubtensorModule::set_element_at(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()); // Set a neuron certificate for it NeuronCertificates::::insert(netuid, hotkey_account_id, certificate); // 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()); @@ -70,7 +103,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); @@ -86,6 +119,33 @@ fn test_replace_neuron() { // Check neuron certificate was reset let certificate = NeuronCertificates::::get(netuid, hotkey_account_id); assert_eq!(certificate, None); + + // 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); }); } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 2455da5d0..cca99f654 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -160,7 +160,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 208, + spec_version: 209, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/support/procedural-fork/src/pallet/parse/storage.rs b/support/procedural-fork/src/pallet/parse/storage.rs index 811832427..64a5e685b 100644 --- a/support/procedural-fork/src/pallet/parse/storage.rs +++ b/support/procedural-fork/src/pallet/parse/storage.rs @@ -718,11 +718,11 @@ fn process_generics( "CountedStorageNMap" => StorageKind::CountedNMap, found => { let msg = format!( - "Invalid pallet::storage, expected ident: `StorageValue` or \ + "Invalid pallet::storage, expected ident: `StorageValue` or \ `StorageMap` or `CountedStorageMap` or `StorageDoubleMap` or `StorageNMap` or `CountedStorageNMap` \ in order to expand metadata, found `{}`.", - found, - ); + found, + ); return Err(syn::Error::new(segment.ident.span(), msg)); } }; diff --git a/support/procedural-fork/src/runtime/parse/mod.rs b/support/procedural-fork/src/runtime/parse/mod.rs index a6a49e814..494ab2c53 100644 --- a/support/procedural-fork/src/runtime/parse/mod.rs +++ b/support/procedural-fork/src/runtime/parse/mod.rs @@ -255,19 +255,19 @@ impl Def { }; let def = Def { - input, - runtime_struct: runtime_struct.ok_or_else(|| { - syn::Error::new(item_span, + input, + runtime_struct: runtime_struct.ok_or_else(|| { + syn::Error::new(item_span, "Missing Runtime. Please add a struct inside the module and annotate it with `#[runtime::runtime]`" ) - })?, - pallets, - runtime_types: runtime_types.ok_or_else(|| { - syn::Error::new(item_span, + })?, + pallets, + runtime_types: runtime_types.ok_or_else(|| { + syn::Error::new(item_span, "Missing Runtime Types. Please annotate the runtime struct with `#[runtime::derive]`" ) - })?, - }; + })?, + }; Ok(def) }