From 4ac0e7325a2db6e205252358ae73461d43e2ae04 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 20:02:10 -0400 Subject: [PATCH 01/10] update trim test to check UID map changed --- pallets/admin-utils/src/tests/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index b6cafb71b7..71a2f7be3c 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -2631,6 +2631,13 @@ fn test_trim_to_max_allowed_uids() { // Actual number of neurons on the network updated after trimming assert_eq!(SubnetworkN::::get(netuid), new_max_n); + for i in 0..new_max_n { + let i = i as u16; + let hotkey = Keys::::get(netuid, i); + let uid = Uids::::get(netuid, hotkey); + assert_eq!(uid.unwrap(), i); + } + // Non existent subnet assert_err!( AdminUtils::sudo_trim_to_max_allowed_uids( From 3e00e4163aa19cfc536124f36b1f1a63b35d86d4 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 20:14:48 -0400 Subject: [PATCH 02/10] bump spec --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a1629cdafb..e597728a60 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -223,7 +223,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: 322, + spec_version: 323, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From b0590ec8c6dd891fd65b62edcfc004b56bd7ddad Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 20:19:40 -0400 Subject: [PATCH 03/10] renumber UIDs during trim --- pallets/subtensor/src/macros/errors.rs | 2 ++ pallets/subtensor/src/subnets/uids.rs | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 98c1742e9a..d8afc1eb1f 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -256,5 +256,7 @@ mod errors { CannotAffordLockCost, /// exceeded the rate limit for associating an EVM key. EvmKeyAssociateRateLimitExceeded, + /// The UID map for the subnet could not be cleared + UidMapCouldNotBeCleared, } } diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index b68fabfbd5..bccb56e58c 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -352,6 +352,21 @@ impl Pallet { } } + // Clear the UID map for the subnet + let clear_result = Uids::::clear_prefix(netuid, u32::MAX, None); + // Shouldn't happen, but possible. + ensure!( + clear_result.maybe_cursor.is_none(), + Error::::UidMapCouldNotBeCleared + ); + + // Insert the new UIDs + for (old_uid, new_uid) in &old_to_new_uid { + // Get the hotkey using Keys map and new UID. + let hotkey = Keys::::get(netuid, *new_uid as u16); + Uids::::insert(netuid, hotkey, *new_uid as u16); + } + // Update the subnet's uid count to reflect the new maximum SubnetworkN::::insert(netuid, max_n); } From 29974a9d72763f78d7efba3a3fe7c4eebbda0041 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 20:30:41 -0400 Subject: [PATCH 04/10] clpy --- pallets/subtensor/src/subnets/uids.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index bccb56e58c..55319306c0 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -361,7 +361,7 @@ impl Pallet { ); // Insert the new UIDs - for (old_uid, new_uid) in &old_to_new_uid { + for new_uid in old_to_new_uid.values() { // Get the hotkey using Keys map and new UID. let hotkey = Keys::::get(netuid, *new_uid as u16); Uids::::insert(netuid, hotkey, *new_uid as u16); From 0ac67c99bc38c20ef261d078551c9c7346346f41 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 20:40:41 -0400 Subject: [PATCH 05/10] chore: clpy --- pallets/admin-utils/src/tests/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 71a2f7be3c..501363fc01 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -2631,11 +2631,10 @@ fn test_trim_to_max_allowed_uids() { // Actual number of neurons on the network updated after trimming assert_eq!(SubnetworkN::::get(netuid), new_max_n); - for i in 0..new_max_n { - let i = i as u16; + for i in 0..new_max_n.into() { let hotkey = Keys::::get(netuid, i); let uid = Uids::::get(netuid, hotkey); - assert_eq!(uid.unwrap(), i); + assert_eq!(uid, Some(i)); } // Non existent subnet From 930ba5cefad650d948f679fe4a5c6d23177f22aa Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 21:38:53 -0400 Subject: [PATCH 06/10] handle AssociatedEvmAddress in trim --- pallets/admin-utils/src/tests/mod.rs | 24 ++++++++++++++++++++++++ pallets/subtensor/src/subnets/uids.rs | 2 ++ 2 files changed, 26 insertions(+) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 501363fc01..18c5e79b2f 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -2492,6 +2492,28 @@ fn test_trim_to_max_allowed_uids() { BlockAtRegistration::::set(netuid, 6, now); BlockAtRegistration::::set(netuid, 11, now); + // Set some evm addresses + AssociatedEvmAddress::::insert( + netuid, + 6, + (sp_core::H160::from_slice(b"0x12345678901234567890"), now), + ); + AssociatedEvmAddress::::insert( + netuid, + 11, + (sp_core::H160::from_slice(b"0xA2345678901234567890"), now), + ); + AssociatedEvmAddress::::insert( + netuid, + 7, + (sp_core::H160::from_slice(b"0xB2345678901234567890"), now), + ); + AssociatedEvmAddress::::insert( + netuid, + 14, + (sp_core::H160::from_slice(b"0xC2345678901234567890"), now), + ); + // And some temporally immune uids Keys::::insert(netuid, 7, sn_owner_hotkey1); Uids::::insert(netuid, sn_owner_hotkey1, 7); @@ -2574,6 +2596,7 @@ fn test_trim_to_max_allowed_uids() { for uid in new_max_n..max_n { assert!(!Keys::::contains_key(netuid, uid)); assert!(!BlockAtRegistration::::contains_key(netuid, uid)); + assert!(!AssociatedEvmAddress::::contains_key(netuid, uid)); for mecid in 0..mechanism_count.into() { let netuid_index = SubtensorModule::get_mechanism_storage_index(netuid, MechId::from(mecid)); @@ -2631,6 +2654,7 @@ fn test_trim_to_max_allowed_uids() { // Actual number of neurons on the network updated after trimming assert_eq!(SubnetworkN::::get(netuid), new_max_n); + // Uids match enumeration order for i in 0..new_max_n.into() { let hotkey = Keys::::get(netuid, i); let uid = Uids::::get(netuid, hotkey); diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index 55319306c0..80cacfe276 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -209,6 +209,7 @@ impl Pallet { #[allow(unknown_lints)] Keys::::remove(netuid, neuron_uid); BlockAtRegistration::::remove(netuid, neuron_uid); + AssociatedEvmAddress::::remove(netuid, neuron_uid); for mecid in 0..mechanisms_count { let netuid_index = Self::get_mechanism_storage_index(netuid, mecid.into()); Weights::::remove(netuid_index, neuron_uid); @@ -315,6 +316,7 @@ impl Pallet { // Swap uid specific storage items to new compressed positions Keys::::swap(netuid, old_neuron_uid, netuid, new_neuron_uid); + AssociatedEvmAddress::::swap(netuid, old_neuron_uid, netuid, new_neuron_uid); BlockAtRegistration::::swap(netuid, old_neuron_uid, netuid, new_neuron_uid); for mecid in 0..mechanisms_count { From 20db6a0737ddd1881e0bd2d49c741d8f9973cc60 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 21:44:22 -0400 Subject: [PATCH 07/10] chore: lock --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5c5c71174..6b5204cb2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6316,11 +6316,11 @@ dependencies = [ [[package]] name = "is_executable" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a1b5bad6f9072935961dfbf1cced2f3d129963d091b6f69f007fe04e758ae2" +checksum = "baabb8b4867b26294d818bf3f651a454b6901431711abb96e296245888d6e8c4" dependencies = [ - "winapi", + "windows-sys 0.60.2", ] [[package]] From 7974e9946026e49af27e40bd447422cae703404d Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Sun, 28 Sep 2025 22:03:56 -0400 Subject: [PATCH 08/10] fix h160 literals --- pallets/admin-utils/src/tests/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 18c5e79b2f..7544632121 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -2496,22 +2496,22 @@ fn test_trim_to_max_allowed_uids() { AssociatedEvmAddress::::insert( netuid, 6, - (sp_core::H160::from_slice(b"0x12345678901234567890"), now), + (sp_core::H160::from_slice(b"12345678901234567890"), now), ); AssociatedEvmAddress::::insert( netuid, 11, - (sp_core::H160::from_slice(b"0xA2345678901234567890"), now), + (sp_core::H160::from_slice(b"A2345678901234567890"), now), ); AssociatedEvmAddress::::insert( netuid, 7, - (sp_core::H160::from_slice(b"0xB2345678901234567890"), now), + (sp_core::H160::from_slice(b"B2345678901234567890"), now), ); AssociatedEvmAddress::::insert( netuid, 14, - (sp_core::H160::from_slice(b"0xC2345678901234567890"), now), + (sp_core::H160::from_slice(b"C2345678901234567890"), now), ); // And some temporally immune uids From 94d5ce1335e26bf5ffa32dbe1ad967779190e2c3 Mon Sep 17 00:00:00 2001 From: Loris Moulin Date: Mon, 29 Sep 2025 15:48:03 -0300 Subject: [PATCH 09/10] added assert for remapped evm address --- pallets/admin-utils/src/tests/mod.rs | 34 ++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 7544632121..ffb50379c9 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -2492,34 +2492,34 @@ fn test_trim_to_max_allowed_uids() { BlockAtRegistration::::set(netuid, 6, now); BlockAtRegistration::::set(netuid, 11, now); + // And some temporally immune uids + Keys::::insert(netuid, 7, sn_owner_hotkey1); + Uids::::insert(netuid, sn_owner_hotkey1, 7); + Keys::::insert(netuid, 14, sn_owner_hotkey2); + Uids::::insert(netuid, sn_owner_hotkey2, 14); + // Set some evm addresses AssociatedEvmAddress::::insert( netuid, 6, - (sp_core::H160::from_slice(b"12345678901234567890"), now), + (sp_core::H160::from_slice(b"12345678901234567891"), now), ); AssociatedEvmAddress::::insert( netuid, - 11, - (sp_core::H160::from_slice(b"A2345678901234567890"), now), + 10, + (sp_core::H160::from_slice(b"12345678901234567892"), now), ); AssociatedEvmAddress::::insert( netuid, - 7, - (sp_core::H160::from_slice(b"B2345678901234567890"), now), + 12, + (sp_core::H160::from_slice(b"12345678901234567893"), now), ); AssociatedEvmAddress::::insert( netuid, 14, - (sp_core::H160::from_slice(b"C2345678901234567890"), now), + (sp_core::H160::from_slice(b"12345678901234567894"), now), ); - // And some temporally immune uids - Keys::::insert(netuid, 7, sn_owner_hotkey1); - Uids::::insert(netuid, sn_owner_hotkey1, 7); - Keys::::insert(netuid, 14, sn_owner_hotkey2); - Uids::::insert(netuid, sn_owner_hotkey2, 14); - // Populate Weights and Bonds storage items to test trimming // Create weights and bonds that span across the range that will be trimmed for uid in 0..max_n { @@ -2661,6 +2661,16 @@ fn test_trim_to_max_allowed_uids() { assert_eq!(uid, Some(i)); } + // EVM association have been remapped correctly (uids: 7 -> 2, 14 -> 7) + assert_eq!( + AssociatedEvmAddress::::get(netuid, 2), + Some((sp_core::H160::from_slice(b"12345678901234567891"), now)) + ); + assert_eq!( + AssociatedEvmAddress::::get(netuid, 7), + Some((sp_core::H160::from_slice(b"12345678901234567894"), now)) + ); + // Non existent subnet assert_err!( AdminUtils::sudo_trim_to_max_allowed_uids( From 82b3f31ff10e38eaa47dfc2595b09d48d0bc9031 Mon Sep 17 00:00:00 2001 From: Loris Moulin Date: Mon, 29 Sep 2025 17:50:23 -0300 Subject: [PATCH 10/10] make immune limit error more explicit --- pallets/admin-utils/src/tests/mod.rs | 10 +++------- pallets/subtensor/src/macros/errors.rs | 2 ++ pallets/subtensor/src/subnets/uids.rs | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index ffb50379c9..b83604b69a 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -2713,7 +2713,7 @@ fn test_trim_to_max_allowed_uids_too_many_immune() { MaxRegistrationsPerBlock::::insert(netuid, 256); TargetRegistrationsPerInterval::::insert(netuid, 256); ImmuneOwnerUidsLimit::::insert(netuid, 2); - MinAllowedUids::::set(netuid, 4); + MinAllowedUids::::set(netuid, 2); // Add 5 neurons let max_n = 5; @@ -2751,7 +2751,7 @@ fn test_trim_to_max_allowed_uids_too_many_immune() { netuid, 4 ), - pallet_subtensor::Error::::InvalidValue + pallet_subtensor::Error::::TrimmingWouldExceedMaxImmunePercentage ); // Try to trim to 3 UIDs - this should also fail because 4/3 > 80% immune (>= 80%) @@ -2761,7 +2761,7 @@ fn test_trim_to_max_allowed_uids_too_many_immune() { netuid, 3 ), - pallet_subtensor::Error::::InvalidValue + pallet_subtensor::Error::::TrimmingWouldExceedMaxImmunePercentage ); // Now test a scenario where trimming should succeed @@ -2773,10 +2773,6 @@ fn test_trim_to_max_allowed_uids_too_many_immune() { Uids::::remove(netuid, hotkey_to_remove); BlockAtRegistration::::remove(netuid, uid_to_remove); - // Now we have 3 immune out of 4 total UIDs - // Try to trim to 3 UIDs - this should succeed because 3/3 = 100% immune, but that's exactly 80% - // Wait, 100% is > 80%, so this should fail. Let me test with a scenario where we have fewer immune UIDs - // Remove another immune UID to make it 2 immune out of 3 total let uid_to_remove2 = 2; let hotkey_to_remove2 = U256::from(uid_to_remove2 * 1000 + 1000); diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index d8afc1eb1f..fbae1e1075 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -258,5 +258,7 @@ mod errors { EvmKeyAssociateRateLimitExceeded, /// The UID map for the subnet could not be cleared UidMapCouldNotBeCleared, + /// Trimming would exceed the max immune neurons percentage + TrimmingWouldExceedMaxImmunePercentage, } } diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index 80cacfe276..4b33a5e737 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -162,7 +162,7 @@ impl Pallet { let immune_percentage = Percent::from_rational(immune_count, max_n); ensure!( immune_percentage < T::MaxImmuneUidsPercentage::get(), - Error::::InvalidValue + Error::::TrimmingWouldExceedMaxImmunePercentage ); // Get all emissions with their UIDs and sort by emission (descending)