Skip to content

Commit 0485b69

Browse files
committed
Add multi-mechanism test for network dissolve
1 parent bb83235 commit 0485b69

File tree

1 file changed

+104
-2
lines changed

1 file changed

+104
-2
lines changed

pallets/subtensor/src/tests/networks.rs

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use crate::*;
44
use frame_support::{assert_err, assert_ok};
55
use frame_system::Config;
66
use sp_core::U256;
7-
use sp_std::collections::btree_map::BTreeMap;
7+
use sp_std::collections::{btree_map::BTreeMap, vec_deque::VecDeque};
88
use substrate_fixed::types::{I96F32, U64F64, U96F32};
9-
use subtensor_runtime_common::{NetUidStorageIndex, TaoCurrency};
9+
use subtensor_runtime_common::{MechId, NetUidStorageIndex, TaoCurrency};
1010
use subtensor_swap_interface::{OrderType, SwapHandler};
1111

1212
#[test]
@@ -2046,3 +2046,105 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state(
20462046
);
20472047
});
20482048
}
2049+
2050+
#[test]
2051+
fn dissolve_clears_all_mechanism_scoped_maps_for_all_mechanisms() {
2052+
new_test_ext(0).execute_with(|| {
2053+
// Create a subnet we can dissolve.
2054+
let owner_cold = U256::from(123);
2055+
let owner_hot = U256::from(456);
2056+
let net = add_dynamic_network(&owner_hot, &owner_cold);
2057+
2058+
// We'll use two mechanisms for this subnet.
2059+
MechanismCountCurrent::<Test>::insert(net, MechId::from(2));
2060+
let m0 = MechId::from(0u8);
2061+
let m1 = MechId::from(1u8);
2062+
2063+
let idx0 = SubtensorModule::get_mechanism_storage_index(net, m0);
2064+
let idx1 = SubtensorModule::get_mechanism_storage_index(net, m1);
2065+
2066+
// Minimal content to ensure each storage actually has keys for BOTH mechanisms.
2067+
2068+
// --- Weights (DMAP: (netuid_index, uid) -> Vec<(dest_uid, weight_u16)>)
2069+
Weights::<Test>::insert(idx0, 0u16, vec![(1u16, 1u16)]);
2070+
Weights::<Test>::insert(idx1, 0u16, vec![(2u16, 1u16)]);
2071+
2072+
// --- Bonds (DMAP: (netuid_index, uid) -> Vec<(dest_uid, weight_u16)>)
2073+
Bonds::<Test>::insert(idx0, 0u16, vec![(1u16, 1u16)]);
2074+
Bonds::<Test>::insert(idx1, 0u16, vec![(2u16, 1u16)]);
2075+
2076+
// --- TimelockedWeightCommits (DMAP: (netuid_index, epoch) -> VecDeque<...>)
2077+
let hotkey = U256::from(1);
2078+
TimelockedWeightCommits::<Test>::insert(
2079+
idx0,
2080+
1u64,
2081+
VecDeque::from([(hotkey, 1u64, Default::default(), Default::default())]),
2082+
);
2083+
TimelockedWeightCommits::<Test>::insert(
2084+
idx1,
2085+
2u64,
2086+
VecDeque::from([(hotkey, 2u64, Default::default(), Default::default())]),
2087+
);
2088+
2089+
// --- Incentive (MAP: netuid_index -> Vec<u16>)
2090+
Incentive::<Test>::insert(idx0, vec![1u16, 2u16]);
2091+
Incentive::<Test>::insert(idx1, vec![3u16, 4u16]);
2092+
2093+
// --- LastUpdate (MAP: netuid_index -> Vec<u64>)
2094+
LastUpdate::<Test>::insert(idx0, vec![42u64]);
2095+
LastUpdate::<Test>::insert(idx1, vec![84u64]);
2096+
2097+
// Sanity: keys are present before dissolve.
2098+
assert!(Weights::<Test>::contains_key(idx0, 0u16));
2099+
assert!(Weights::<Test>::contains_key(idx1, 0u16));
2100+
assert!(Bonds::<Test>::contains_key(idx0, 0u16));
2101+
assert!(Bonds::<Test>::contains_key(idx1, 0u16));
2102+
assert!(TimelockedWeightCommits::<Test>::contains_key(idx0, 1u64));
2103+
assert!(TimelockedWeightCommits::<Test>::contains_key(idx1, 2u64));
2104+
assert!(Incentive::<Test>::contains_key(idx0));
2105+
assert!(Incentive::<Test>::contains_key(idx1));
2106+
assert!(LastUpdate::<Test>::contains_key(idx0));
2107+
assert!(LastUpdate::<Test>::contains_key(idx1));
2108+
assert!(MechanismCountCurrent::<Test>::contains_key(net));
2109+
2110+
// --- Dissolve the subnet ---
2111+
assert_ok!(SubtensorModule::do_dissolve_network(net));
2112+
2113+
// After dissolve, ALL mechanism-scoped items must be cleared for ALL mechanisms.
2114+
2115+
// Weights/Bonds double-maps should have no entries under either index.
2116+
assert!(Weights::<Test>::iter_prefix(idx0).next().is_none());
2117+
assert!(Weights::<Test>::iter_prefix(idx1).next().is_none());
2118+
assert!(Bonds::<Test>::iter_prefix(idx0).next().is_none());
2119+
assert!(Bonds::<Test>::iter_prefix(idx1).next().is_none());
2120+
2121+
// WeightCommits (OptionQuery) should have no keys remaining.
2122+
assert!(WeightCommits::<Test>::iter_prefix(idx0).next().is_none());
2123+
assert!(WeightCommits::<Test>::iter_prefix(idx1).next().is_none());
2124+
assert!(!WeightCommits::<Test>::contains_key(idx0, owner_hot));
2125+
assert!(!WeightCommits::<Test>::contains_key(idx1, owner_cold));
2126+
2127+
// TimelockedWeightCommits (ValueQuery) — ensure both prefix spaces empty and keys gone.
2128+
assert!(
2129+
TimelockedWeightCommits::<Test>::iter_prefix(idx0)
2130+
.next()
2131+
.is_none()
2132+
);
2133+
assert!(
2134+
TimelockedWeightCommits::<Test>::iter_prefix(idx1)
2135+
.next()
2136+
.is_none()
2137+
);
2138+
assert!(!TimelockedWeightCommits::<Test>::contains_key(idx0, 1u64));
2139+
assert!(!TimelockedWeightCommits::<Test>::contains_key(idx1, 2u64));
2140+
2141+
// Single-map per-mechanism vectors cleared.
2142+
assert!(!Incentive::<Test>::contains_key(idx0));
2143+
assert!(!Incentive::<Test>::contains_key(idx1));
2144+
assert!(!LastUpdate::<Test>::contains_key(idx0));
2145+
assert!(!LastUpdate::<Test>::contains_key(idx1));
2146+
2147+
// MechanismCountCurrent cleared
2148+
assert!(!MechanismCountCurrent::<Test>::contains_key(net));
2149+
});
2150+
}

0 commit comments

Comments
 (0)