From d00b27f02c48f225d7e07bffa24e713ec9c7cd27 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Tue, 3 Sep 2024 13:27:40 -0700 Subject: [PATCH 1/9] unstake in remove_network --- pallets/subtensor/src/coinbase/root.rs | 41 ++++++++++++++++++-------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index 067d5855b..2d9e30d13 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -1140,30 +1140,47 @@ impl Pallet { let owner_coldkey: T::AccountId = SubnetOwner::::get(netuid); let reserved_amount: u64 = Self::get_subnet_locked_balance(netuid); - // --- 2. Remove network count. + // --- 2. Unstake nominators and delegates + let stake_entries: Vec<(T::AccountId, T::AccountId, u64)> = + as IterableStorageDoubleMap>::iter() + .filter(|(hotkey, _, _)| Uids::::contains_key(netuid, hotkey)) + .collect(); + + for (hotkey, coldkey, stake) in stake_entries { + let staking_key = if Self::hotkey_is_delegate(&hotkey) { + Owner::::get(&hotkey) + } else { + coldkey.clone() + }; + + Self::add_balance_to_coldkey_account(&staking_key, stake); + >::remove(&hotkey, &coldkey); + } + + // --- 3. Remove network count. SubnetworkN::::remove(netuid); - // --- 3. Remove network modality storage. + // --- 4. Remove network modality storage. NetworkModality::::remove(netuid); - // --- 4. Remove netuid from added networks. + // --- 5. Remove netuid from added networks. NetworksAdded::::remove(netuid); - // --- 5. Decrement the network counter. + // --- 6. Decrement the network counter. TotalNetworks::::mutate(|n: &mut u16| *n = n.saturating_sub(1)); - // --- 6. Remove various network-related storages. + // --- 7. Remove various network-related storages. NetworkRegisteredAt::::remove(netuid); - // --- 7. Remove incentive mechanism memory. + // --- 8. Remove incentive mechanism memory. let _ = Uids::::clear_prefix(netuid, u32::MAX, None); let _ = Keys::::clear_prefix(netuid, u32::MAX, None); let _ = Bonds::::clear_prefix(netuid, u32::MAX, None); - // --- 8. Removes the weights for this subnet (do not remove). + // --- 9. Removes the weights for this subnet (do not remove). let _ = Weights::::clear_prefix(netuid, u32::MAX, None); - // --- 9. Iterate over stored weights and fill the matrix. + // --- 10. Iterate over stored weights and fill the matrix. for (uid_i, weights_i) in as IterableStorageDoubleMap>>::iter_prefix( Self::get_root_netuid(), @@ -1181,7 +1198,7 @@ impl Pallet { Weights::::insert(Self::get_root_netuid(), uid_i, modified_weights); } - // --- 10. Remove various network-related parameters. + // --- 11. Remove various network-related parameters. Rank::::remove(netuid); Trust::::remove(netuid); Active::::remove(netuid); @@ -1194,7 +1211,7 @@ impl Pallet { ValidatorPermit::::remove(netuid); ValidatorTrust::::remove(netuid); - // --- 11. Erase network parameters. + // --- 12. Erase network parameters. Tempo::::remove(netuid); Kappa::::remove(netuid); Difficulty::::remove(netuid); @@ -1208,12 +1225,12 @@ impl Pallet { POWRegistrationsThisInterval::::remove(netuid); BurnRegistrationsThisInterval::::remove(netuid); - // --- 12. Add the balance back to the owner. + // --- 13. Add the balance back to the owner. Self::add_balance_to_coldkey_account(&owner_coldkey, reserved_amount); Self::set_subnet_locked_balance(netuid, 0); SubnetOwner::::remove(netuid); - // --- 13. Remove subnet identity if it exists. + // --- 14. Remove subnet identity if it exists. if SubnetIdentities::::contains_key(netuid) { SubnetIdentities::::remove(netuid); Self::deposit_event(Event::SubnetIdentityRemoved(netuid)); From d497fe159d30cd896ab7841f8410e1e0aa7fbfca Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Tue, 3 Sep 2024 13:28:07 -0700 Subject: [PATCH 2/9] test unstake remove_network --- pallets/subtensor/tests/root.rs | 176 ++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index caf1e5935..42ca182ac 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -983,6 +983,182 @@ fn test_dissolve_network_does_not_exist_err() { }); } +#[test] +fn test_dissolve_network_unstake_nominators_ok() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 30; + let hotkey = U256::from(1); + let coldkey = U256::from(2); + let stake: u64 = 1000; + + // Set up the network and stake + add_network(netuid, 0, 0); + pallet_subtensor::SubnetOwner::::insert(netuid, coldkey); + register_ok_neuron(netuid, hotkey, coldkey, 3); + + SubtensorModule::add_balance_to_coldkey_account(&coldkey, 10); + let initial_balance: u64 = SubtensorModule::get_coldkey_balance(&coldkey); + + >::insert(hotkey, coldkey, stake); + pallet_subtensor::Uids::::insert(netuid, hotkey, 0); + + // Call the dissolve_network function, which should trigger unstaking + assert_ok!(SubtensorModule::dissolve_network( + RuntimeOrigin::root(), + coldkey, + netuid + )); + + let new_balance: u64 = SubtensorModule::get_coldkey_balance(&coldkey); + + // Check that the balance was correctly updated and the stake was removed + assert_eq!(new_balance, initial_balance + stake); + assert!(!>::contains_key( + hotkey, coldkey + )); + }); +} + +#[test] +fn test_dissolve_network_unstake_delegate_ok() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 30; + let hotkey = U256::from(1); + let coldkey = U256::from(2); + let delegate_coldkey = U256::from(3); + let stake: u64 = 1000; + + // Set up the network and associate the coldkey with the hotkey + add_network(netuid, 0, 0); + pallet_subtensor::SubnetOwner::::insert(netuid, coldkey); + register_ok_neuron(netuid, hotkey, coldkey, 3); + >::insert(hotkey, coldkey, stake); + pallet_subtensor::Uids::::insert(netuid, hotkey, 0); + + // Insert delegate ownership for the hotkey + pallet_subtensor::Owner::::insert(hotkey, coldkey); + + // Ensure the hotkey is treated as a delegate + assert_ok!(SubtensorModule::do_become_delegate( + <::RuntimeOrigin>::signed(coldkey), + hotkey, + u16::MAX / 10 + )); + + // Update the owner to the delegate coldkey + pallet_subtensor::Owner::::insert(hotkey, delegate_coldkey); + + let initial_delegate_balance = SubtensorModule::get_coldkey_balance(&delegate_coldkey); + + // Call the dissolve_network function + assert_ok!(SubtensorModule::dissolve_network( + RuntimeOrigin::root(), + coldkey, + netuid + )); + + let new_delegate_balance: u64 = SubtensorModule::get_coldkey_balance(&delegate_coldkey); + + // Check that the delegate's balance was correctly updated and the stake was removed + assert_eq!(new_delegate_balance, initial_delegate_balance + stake); + assert!(!>::contains_key( + hotkey, coldkey + )); + }); +} + +#[test] +fn test_dissolve_network_unstake_nominators_and_delegates_partial_match() { + new_test_ext(1).execute_with(|| { + let netuid1: u16 = 30; + let hotkey1 = U256::from(1); + let coldkey1 = U256::from(2); + let stake1: u64 = 1000; + + let netuid2: u16 = 31; + let hotkey2 = U256::from(3); + let coldkey2 = U256::from(4); + let stake2: u64 = 500; + + // Set up two distinct networks and stakes + add_network(netuid1, 0, 0); + add_network(netuid2, 0, 0); + pallet_subtensor::SubnetOwner::::insert(netuid1, coldkey1); + pallet_subtensor::SubnetOwner::::insert(netuid2, coldkey2); + register_ok_neuron(netuid1, hotkey1, coldkey1, 3); + register_ok_neuron(netuid2, hotkey2, coldkey2, 3); + >::insert(hotkey1, coldkey1, stake1); + >::insert(hotkey2, coldkey2, stake2); + pallet_subtensor::Uids::::insert(netuid1, hotkey1, 0); // Only hotkey1 is in Uids for the first network + + let initial_balance1: u64 = SubtensorModule::get_coldkey_balance(&coldkey1); + let initial_balance2: u64 = SubtensorModule::get_coldkey_balance(&coldkey2); + + // Call the dissolve_network function on the second network, which should only affect hotkey2 + assert_ok!(SubtensorModule::dissolve_network( + RuntimeOrigin::root(), + coldkey2, + netuid2 + )); + + let new_balance1: u64 = SubtensorModule::get_coldkey_balance(&coldkey1); + let new_balance2: u64 = SubtensorModule::get_coldkey_balance(&coldkey2); + + // Check that only the second network's stake was removed and balance updated + assert_eq!(new_balance1, initial_balance1); + assert_eq!(new_balance2, initial_balance2 + stake2); // Only change for hotkey2 + assert!(>::contains_key( + hotkey1, coldkey1 + )); + assert!(!>::contains_key( + hotkey2, coldkey2 + )); + }); +} + +#[test] +fn test_dissolve_network_unstake_multiple_stakes_same_hotkey() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 30; + let hotkey = U256::from(1); + let coldkey1 = U256::from(2); + let coldkey2 = U256::from(3); + let stake1: u64 = 1000; + let stake2: u64 = 500; + + // Set up the network and multiple stakes + add_network(netuid, 0, 0); + pallet_subtensor::SubnetOwner::::insert(netuid, coldkey1); + register_ok_neuron(netuid, hotkey, coldkey1, 3); + >::insert(hotkey, coldkey1, stake1); + >::insert(hotkey, coldkey2, stake2); + pallet_subtensor::Uids::::insert(netuid, hotkey, 0); + + let initial_balance1: u64 = SubtensorModule::get_coldkey_balance(&coldkey1); + let initial_balance2: u64 = SubtensorModule::get_coldkey_balance(&coldkey2); + + // Call the dissolve_network function + assert_ok!(SubtensorModule::dissolve_network( + RuntimeOrigin::root(), + coldkey1, + netuid + )); + + let new_balance1: u64 = SubtensorModule::get_coldkey_balance(&coldkey1); + let new_balance2: u64 = SubtensorModule::get_coldkey_balance(&coldkey2); + + // Check that both stakes were removed and the balances updated + assert_eq!(new_balance1, initial_balance1 + stake1); + assert_eq!(new_balance2, initial_balance2 + stake2); + assert!(!>::contains_key( + hotkey, coldkey1 + )); + assert!(!>::contains_key( + hotkey, coldkey2 + )); + }); +} + #[test] fn test_user_add_network_with_identity_fields_ok() { new_test_ext(1).execute_with(|| { From e3f7f55f36a0545f9eb216974f6e1286dfe7276a Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:11:24 -0700 Subject: [PATCH 3/9] refactor unstaking in remove_network --- pallets/subtensor/src/coinbase/root.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index 2d9e30d13..3ce270833 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -1141,18 +1141,23 @@ impl Pallet { let reserved_amount: u64 = Self::get_subnet_locked_balance(netuid); // --- 2. Unstake nominators and delegates - let stake_entries: Vec<(T::AccountId, T::AccountId, u64)> = + let stake_entries: Vec<(T::AccountId, T::AccountId, T::AccountId, u64)> = as IterableStorageDoubleMap>::iter() - .filter(|(hotkey, _, _)| Uids::::contains_key(netuid, hotkey)) - .collect(); + .filter_map(|(hotkey, coldkey, stake)| { + if !Uids::::contains_key(netuid, &hotkey) { + return None; + } - for (hotkey, coldkey, stake) in stake_entries { - let staking_key = if Self::hotkey_is_delegate(&hotkey) { - Owner::::get(&hotkey) - } else { - coldkey.clone() - }; + let staking_key = match Self::hotkey_is_delegate(&hotkey) { + true => Owner::::get(&hotkey), + false => coldkey.clone(), + }; + + Some((staking_key, hotkey, coldkey, stake)) + }) + .collect::>(); + for (staking_key, hotkey, coldkey, stake) in stake_entries { Self::add_balance_to_coldkey_account(&staking_key, stake); >::remove(&hotkey, &coldkey); } From 82af5ad86bafd39e42937d2c11c8a53bdbfeca89 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:11:44 -0700 Subject: [PATCH 4/9] add test --- pallets/subtensor/tests/root.rs | 137 ++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index 42ca182ac..bafe89b5c 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -1159,6 +1159,143 @@ fn test_dissolve_network_unstake_multiple_stakes_same_hotkey() { }); } +#[test] +fn test_dissolve_network_complex_state() { + new_test_ext(1).execute_with(|| { + let num_networks = 10; + let mut netuids = vec![]; + let mut hotkeys = vec![]; + let mut coldkeys = vec![]; + let mut stakes = vec![]; + let mut subnet_owners = vec![]; + let mut initial_balances = vec![]; + + // Setup: Create 10 networks and populate each with hotkeys, coldkeys, and stakes + for netuid in 1..=num_networks { + let hotkey_base = U256::from(netuid * 10 + 1); + let coldkey_base = U256::from(netuid * 10 + 2); + + netuids.push(netuid); + subnet_owners.push(coldkey_base); + + add_network(netuid, 0, 0); + pallet_subtensor::SubnetOwner::::insert(netuid, coldkey_base); + SubtensorModule::set_max_registrations_per_block(netuid, 4096); + SubtensorModule::set_target_registrations_per_interval(netuid, 9999); + + for i in 1..=5 { + // 5 UIDs in each network + let hotkey = U256::from(hotkey_base.as_u64() + i); + let coldkey = U256::from(coldkey_base.as_u64() + i); + + let initial_balance = SubtensorModule::get_coldkey_balance(&coldkey_base); + let new_balance = initial_balance + i * 2; + initial_balances.push(new_balance); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, new_balance); + + hotkeys.push(hotkey); + coldkeys.push(coldkey); + + // Alternate between having stake and no stake + if i % 2 == 0 { + let stake = (i + 1) as u64 * 1000; + stakes.push(stake); + + register_ok_neuron(netuid, hotkey, coldkey, 3); + >::insert(hotkey, coldkey, stake); + + log::debug!( + "Registered neuron {} in network {} with coldkey {} and stake {}", + hotkey, + netuid, + coldkey, + stake + ); + } else { + stakes.push(0); // No stake for this UID + register_ok_neuron(netuid, hotkey, coldkey, 3); + + log::debug!( + "Registered neuron {} in network {} with coldkey {}, no stake", + hotkey, + netuid, + coldkey + ); + } + + pallet_subtensor::Uids::::insert(netuid, hotkey, i as u16); + // Add UID to network + } + } + + // Test: Dissolve each network and ensure correct unstaking behavior + for (netuid, subnet_owner) in netuids.iter().zip(subnet_owners.iter()) { + log::debug!( + "Dissolving network {} with subnet owner {}", + netuid, + subnet_owner + ); + assert_ok!(SubtensorModule::dissolve_network( + RuntimeOrigin::root(), + *subnet_owner, + *netuid + )); + } + + // Verify: Check that all stakes were correctly unstaked and balances updated for stakeholders + for i in 0..hotkeys.len() { + let hotkey = &hotkeys[i]; + let coldkey = &coldkeys[i]; + let stake = stakes[i]; + + log::debug!( + "Checking stake for hotkey {} and coldkey {}: stake = {}", + hotkey, + coldkey, + stake + ); + + // If there was a stake, check if the balance was added to the correct stakeholder (hotkey owner or coldkey) + if stake > 0 { + let staking_key = if SubtensorModule::hotkey_is_delegate(hotkey) { + pallet_subtensor::Owner::::get(hotkey) + } else { + coldkey.clone() + }; + + let new_balance = SubtensorModule::get_coldkey_balance(&staking_key); + + log::debug!( + "Hotkey {} has staking key {}. New balance is {}, expected stake is {}", + hotkey, + staking_key, + new_balance, + stake + ); + + assert_eq!(new_balance, stake + initial_balances[i]); + } + } + + // Ensure that all stakes were removed + for (_, ((hotkey, coldkey), _stake)) in hotkeys + .iter() + .zip(coldkeys.iter()) + .zip(stakes.iter()) + .enumerate() + { + log::debug!( + "Checking if stake for hotkey {} and coldkey {} was removed", + hotkey, + coldkey + ); + assert!(!>::contains_key( + hotkey, coldkey + )); + } + }); +} + #[test] fn test_user_add_network_with_identity_fields_ok() { new_test_ext(1).execute_with(|| { From 926699a093af5f233aa808ec40640762d9df890a Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:21:16 -0700 Subject: [PATCH 5/9] clippy --- pallets/subtensor/tests/root.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index bafe89b5c..04946a2fc 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -1198,7 +1198,7 @@ fn test_dissolve_network_complex_state() { // Alternate between having stake and no stake if i % 2 == 0 { - let stake = (i + 1) as u64 * 1000; + let stake = (i + 1) * 1000; stakes.push(stake); register_ok_neuron(netuid, hotkey, coldkey, 3); @@ -1260,7 +1260,7 @@ fn test_dissolve_network_complex_state() { let staking_key = if SubtensorModule::hotkey_is_delegate(hotkey) { pallet_subtensor::Owner::::get(hotkey) } else { - coldkey.clone() + *coldkey }; let new_balance = SubtensorModule::get_coldkey_balance(&staking_key); @@ -1278,12 +1278,7 @@ fn test_dissolve_network_complex_state() { } // Ensure that all stakes were removed - for (_, ((hotkey, coldkey), _stake)) in hotkeys - .iter() - .zip(coldkeys.iter()) - .zip(stakes.iter()) - .enumerate() - { + for ((hotkey, coldkey), _stake) in hotkeys.iter().zip(coldkeys.iter()).zip(stakes.iter()) { log::debug!( "Checking if stake for hotkey {} and coldkey {} was removed", hotkey, From 610dbf7a785716d47e5712b12f49c6e680102eb8 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Thu, 5 Sep 2024 07:32:45 -0700 Subject: [PATCH 6/9] improve test --- pallets/subtensor/tests/root.rs | 58 +++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index 04946a2fc..ee7f51b79 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -1211,6 +1211,26 @@ fn test_dissolve_network_complex_state() { coldkey, stake ); + } else if i % 3 == 0 { + let stake = (i + 1) * 1000; + stakes.push(stake); + + register_ok_neuron(netuid, hotkey, coldkey, 3); + >::insert(hotkey, coldkey, stake); + + assert_ok!(SubtensorModule::do_become_delegate( + <::RuntimeOrigin>::signed(coldkey), + hotkey, + u16::MAX / 10 + )); + + log::debug!( + "Registered neuron as delegate {} in network {} with coldkey {} and stake {}", + hotkey, + netuid, + coldkey, + stake + ); } else { stakes.push(0); // No stake for this UID register_ok_neuron(netuid, hotkey, coldkey, 3); @@ -1224,7 +1244,6 @@ fn test_dissolve_network_complex_state() { } pallet_subtensor::Uids::::insert(netuid, hotkey, i as u16); - // Add UID to network } } @@ -1255,35 +1274,24 @@ fn test_dissolve_network_complex_state() { stake ); - // If there was a stake, check if the balance was added to the correct stakeholder (hotkey owner or coldkey) - if stake > 0 { - let staking_key = if SubtensorModule::hotkey_is_delegate(hotkey) { - pallet_subtensor::Owner::::get(hotkey) - } else { - *coldkey - }; - - let new_balance = SubtensorModule::get_coldkey_balance(&staking_key); - - log::debug!( - "Hotkey {} has staking key {}. New balance is {}, expected stake is {}", - hotkey, - staking_key, - new_balance, - stake - ); + let staking_key = if SubtensorModule::hotkey_is_delegate(hotkey) { + pallet_subtensor::Owner::::get(hotkey) + } else { + *coldkey + }; - assert_eq!(new_balance, stake + initial_balances[i]); - } - } + let new_balance = SubtensorModule::get_coldkey_balance(&staking_key); - // Ensure that all stakes were removed - for ((hotkey, coldkey), _stake) in hotkeys.iter().zip(coldkeys.iter()).zip(stakes.iter()) { log::debug!( - "Checking if stake for hotkey {} and coldkey {} was removed", + "Hotkey {} has staking key {}. New balance is {}, expected stake is {}", hotkey, - coldkey + staking_key, + new_balance, + stake ); + + assert_eq!(new_balance, stake + initial_balances[i]); + assert!(!>::contains_key( hotkey, coldkey )); From 7f375f90465f2b6121dc845ab7afb25eb2dfcebc Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:50:57 -0700 Subject: [PATCH 7/9] remove stake with existing function --- pallets/subtensor/src/coinbase/root.rs | 2 +- pallets/subtensor/tests/root.rs | 32 ++++++++------------------ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index 3ce270833..d264858b2 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -1159,7 +1159,7 @@ impl Pallet { for (staking_key, hotkey, coldkey, stake) in stake_entries { Self::add_balance_to_coldkey_account(&staking_key, stake); - >::remove(&hotkey, &coldkey); + Self::decrease_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake); } // --- 3. Remove network count. diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index ee7f51b79..93b90233e 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -1013,9 +1013,7 @@ fn test_dissolve_network_unstake_nominators_ok() { // Check that the balance was correctly updated and the stake was removed assert_eq!(new_balance, initial_balance + stake); - assert!(!>::contains_key( - hotkey, coldkey - )); + assert_eq!(>::get(hotkey, coldkey), 0); }); } @@ -1061,9 +1059,7 @@ fn test_dissolve_network_unstake_delegate_ok() { // Check that the delegate's balance was correctly updated and the stake was removed assert_eq!(new_delegate_balance, initial_delegate_balance + stake); - assert!(!>::contains_key( - hotkey, coldkey - )); + assert_eq!(>::get(hotkey, coldkey), 0); }); } @@ -1107,12 +1103,11 @@ fn test_dissolve_network_unstake_nominators_and_delegates_partial_match() { // Check that only the second network's stake was removed and balance updated assert_eq!(new_balance1, initial_balance1); assert_eq!(new_balance2, initial_balance2 + stake2); // Only change for hotkey2 - assert!(>::contains_key( - hotkey1, coldkey1 - )); - assert!(!>::contains_key( - hotkey2, coldkey2 - )); + assert_eq!( + >::get(hotkey1, coldkey1), + stake1 + ); + assert_eq!(>::get(hotkey2, coldkey2), 0); }); } @@ -1150,12 +1145,8 @@ fn test_dissolve_network_unstake_multiple_stakes_same_hotkey() { // Check that both stakes were removed and the balances updated assert_eq!(new_balance1, initial_balance1 + stake1); assert_eq!(new_balance2, initial_balance2 + stake2); - assert!(!>::contains_key( - hotkey, coldkey1 - )); - assert!(!>::contains_key( - hotkey, coldkey2 - )); + assert_eq!(>::get(hotkey, coldkey1), 0); + assert_eq!(>::get(hotkey, coldkey2), 0); }); } @@ -1291,10 +1282,7 @@ fn test_dissolve_network_complex_state() { ); assert_eq!(new_balance, stake + initial_balances[i]); - - assert!(!>::contains_key( - hotkey, coldkey - )); + assert_eq!(>::get(hotkey, coldkey), 0); } }); } From 734ff5b7367aac7810edfb0b2f99111cf68355ff Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:27:41 -0700 Subject: [PATCH 8/9] simplify unstake logic --- pallets/subtensor/src/coinbase/root.rs | 31 +++++++++++--------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index d264858b2..5f8caade1 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -1141,26 +1141,21 @@ impl Pallet { let reserved_amount: u64 = Self::get_subnet_locked_balance(netuid); // --- 2. Unstake nominators and delegates - let stake_entries: Vec<(T::AccountId, T::AccountId, T::AccountId, u64)> = - as IterableStorageDoubleMap>::iter() - .filter_map(|(hotkey, coldkey, stake)| { - if !Uids::::contains_key(netuid, &hotkey) { - return None; - } - - let staking_key = match Self::hotkey_is_delegate(&hotkey) { - true => Owner::::get(&hotkey), - false => coldkey.clone(), - }; + as IterableStorageDoubleMap>::iter().for_each( + |(hotkey, coldkey, stake)| { + if !Uids::::contains_key(netuid, &hotkey) { + return; + } - Some((staking_key, hotkey, coldkey, stake)) - }) - .collect::>(); + let staking_key = match Self::hotkey_is_delegate(&hotkey) { + true => Owner::::get(&hotkey), + false => coldkey.clone(), + }; - for (staking_key, hotkey, coldkey, stake) in stake_entries { - Self::add_balance_to_coldkey_account(&staking_key, stake); - Self::decrease_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake); - } + Self::add_balance_to_coldkey_account(&staking_key, stake); + Self::decrease_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake); + }, + ); // --- 3. Remove network count. SubnetworkN::::remove(netuid); From 9e6ed02ec3be4cf10bb000cd17e11e123590750d Mon Sep 17 00:00:00 2001 From: johnreedv Date: Thu, 12 Sep 2024 12:05:23 -0700 Subject: [PATCH 9/9] 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 9622c6e2a..b7a347c46 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -142,7 +142,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: 196, + spec_version: 197, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,