Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions pallets/subtensor/src/epoch/run_epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,6 @@ impl<T: Config> Pallet<T> {
} else {
inplace_mask_diag(&mut weights);
}

inplace_mask_diag(&mut weights);
log::trace!("W (permit+diag): {:?}", &weights);

// Mask outdated weights: remove weights referring to deregistered neurons.
Expand Down
59 changes: 51 additions & 8 deletions pallets/subtensor/src/tests/networks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2715,18 +2715,13 @@ fn registered_subnet_counter_is_independent_per_netuid() {
#[test]
fn registered_subnet_counter_survives_dissolve_and_bumps_on_reregistration() {
new_test_ext(1).execute_with(|| {
// Force reuse of the same netuid on re-registration by pinning the
// active subnet cap so the next registration must prune.
SubtensorModule::set_max_subnets(2);

let owner_cold = U256::from(100);
let owner_hot = U256::from(101);
let netuid = add_dynamic_network(&owner_hot, &owner_cold);
assert_eq!(SubtensorModule::get_registered_subnet_counter(netuid), 1);

// Dissolve: counter is intentionally *not* cleared — stale consumers
// can still detect the pre-dereg lifetime if they stored the counter
// value they observed at approval time.
assert_ok!(SubtensorModule::do_dissolve_network(netuid));
assert!(!SubtensorModule::if_subnet_exist(netuid));
assert_eq!(
Expand All @@ -2735,9 +2730,6 @@ fn registered_subnet_counter_survives_dissolve_and_bumps_on_reregistration() {
"dissolve must not clear or reset the counter"
);

// Re-register. With the cap pinned, the prune selector reuses the
// freed netuid; the counter bumps to 2 so that any state still keyed
// to the prior value becomes unreachable under the new registration.
let reg_netuid = add_dynamic_network(&owner_hot, &owner_cold);
assert_eq!(
reg_netuid, netuid,
Expand All @@ -2750,3 +2742,54 @@ fn registered_subnet_counter_survives_dissolve_and_bumps_on_reregistration() {
);
});
}

// --- get_next_netuid tests ---

#[test]
fn test_get_next_netuid_empty_returns_one() {
// With no subnets registered, the first available netuid should be 1 (root = 0 is reserved).
new_test_ext(1).execute_with(|| {
assert_eq!(SubtensorModule::get_next_netuid(), NetUid::from(1));
});
}

#[test]
fn test_get_next_netuid_sequential() {
// When netuids 1..=n are all taken, should return n+1.
new_test_ext(1).execute_with(|| {
for i in 1u16..=5 {
add_network(NetUid::from(i), 1, 0);
}
assert_eq!(SubtensorModule::get_next_netuid(), NetUid::from(6));
});
}

#[test]
fn test_get_next_netuid_skips_to_first_hole() {
// When there's a gap (e.g. 2 was dissolved), should return the earliest free netuid.
new_test_ext(1).execute_with(|| {
add_network(NetUid::from(1), 1, 0);
add_network(NetUid::from(3), 1, 0); // 2 is missing
assert_eq!(SubtensorModule::get_next_netuid(), NetUid::from(2));
});
}

#[test]
fn test_get_next_netuid_root_not_returned() {
// Root (netuid 0) must never be returned, even when no other subnet exists.
new_test_ext(1).execute_with(|| {
assert_ne!(SubtensorModule::get_next_netuid(), NetUid::ROOT);
});
}

#[test]
fn test_get_next_netuid_stable_across_calls() {
// Repeated calls without any state change must return the same value.
new_test_ext(1).execute_with(|| {
add_network(NetUid::from(1), 1, 0);
add_network(NetUid::from(2), 1, 0);
let first = SubtensorModule::get_next_netuid();
let second = SubtensorModule::get_next_netuid();
assert_eq!(first, second);
});
}
Loading