Skip to content

Commit bdf4bac

Browse files
committed
add/update tests
1 parent 22a4d3f commit bdf4bac

File tree

1 file changed

+156
-1
lines changed

1 file changed

+156
-1
lines changed

pallets/subtensor/src/tests/networks.rs

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ fn dissolve_refunds_full_lock_cost_when_no_emission() {
7171
let hot = U256::from(4);
7272
let net = add_dynamic_network(&hot, &cold);
7373

74+
// Mark this subnet as *legacy* so owner refund path is enabled.
75+
let reg_at = NetworkRegisteredAt::<Test>::get(net);
76+
NetworkRegistrationStartBlock::<Test>::put(reg_at.saturating_add(1));
77+
7478
let lock: TaoCurrency = TaoCurrency::from(1_000_000);
7579
SubtensorModule::set_subnet_locked_balance(net, lock);
7680
SubnetTAO::<Test>::insert(net, TaoCurrency::from(0));
@@ -126,6 +130,10 @@ fn dissolve_two_stakers_pro_rata_distribution() {
126130
let oh = U256::from(51);
127131
let net = add_dynamic_network(&oh, &oc);
128132

133+
// Mark this subnet as *legacy* so owner refund path is enabled.
134+
let reg_at = NetworkRegisteredAt::<Test>::get(net);
135+
NetworkRegistrationStartBlock::<Test>::put(reg_at.saturating_add(1));
136+
129137
let (s1_hot, s1_cold, a1) = (U256::from(201), U256::from(301), 300u128);
130138
let (s2_hot, s2_cold, a2) = (U256::from(202), U256::from(302), 700u128);
131139

@@ -134,7 +142,7 @@ fn dissolve_two_stakers_pro_rata_distribution() {
134142

135143
let pot: u64 = 10_000;
136144
SubnetTAO::<Test>::insert(net, TaoCurrency::from(pot));
137-
SubtensorModule::set_subnet_locked_balance(net, 5_000.into()); // owner refund path present but emission = 0
145+
SubtensorModule::set_subnet_locked_balance(net, 5_000.into()); // owner refund path present; emission = 0
138146

139147
// Cold-key balances before
140148
let s1_before = SubtensorModule::get_coldkey_balance(&s1_cold);
@@ -199,6 +207,10 @@ fn dissolve_owner_cut_refund_logic() {
199207
let oh = U256::from(71);
200208
let net = add_dynamic_network(&oh, &oc);
201209

210+
// Mark this subnet as *legacy* so owner refund path is enabled.
211+
let reg_at = NetworkRegisteredAt::<Test>::get(net);
212+
NetworkRegistrationStartBlock::<Test>::put(reg_at.saturating_add(1));
213+
202214
// One staker and a TAO pot (not relevant to refund amount).
203215
let sh = U256::from(77);
204216
let sc = U256::from(88);
@@ -683,6 +695,10 @@ fn destroy_alpha_out_multiple_stakers_pro_rata() {
683695
let owner_hot = U256::from(20);
684696
let netuid = add_dynamic_network(&owner_hot, &owner_cold);
685697

698+
// Mark this subnet as *legacy* so owner refund path is enabled.
699+
let reg_at = NetworkRegisteredAt::<Test>::get(netuid);
700+
NetworkRegistrationStartBlock::<Test>::put(reg_at.saturating_add(1));
701+
686702
// 2. Two stakers on that subnet
687703
let (c1, h1) = (U256::from(111), U256::from(211));
688704
let (c2, h2) = (U256::from(222), U256::from(333));
@@ -779,6 +795,10 @@ fn destroy_alpha_out_many_stakers_complex_distribution() {
779795
SubtensorModule::set_max_registrations_per_block(netuid, 1_000u16);
780796
SubtensorModule::set_target_registrations_per_interval(netuid, 1_000u16);
781797

798+
// Mark this subnet as *legacy* so owner refund path is enabled.
799+
let reg_at = NetworkRegisteredAt::<Test>::get(netuid);
800+
NetworkRegistrationStartBlock::<Test>::put(reg_at.saturating_add(1));
801+
782802
// Runtime-exact min amount = min_stake + fee
783803
let min_amount = {
784804
let min_stake = DefaultMinStake::<Test>::get();
@@ -914,6 +934,141 @@ fn destroy_alpha_out_many_stakers_complex_distribution() {
914934
});
915935
}
916936

937+
#[test]
938+
fn destroy_alpha_out_refund_gating_by_registration_block() {
939+
// ──────────────────────────────────────────────────────────────────────
940+
// Case A: LEGACY subnet → refund applied
941+
// ──────────────────────────────────────────────────────────────────────
942+
new_test_ext(0).execute_with(|| {
943+
// Owner + subnet
944+
let owner_cold = U256::from(10_000);
945+
let owner_hot = U256::from(20_000);
946+
let netuid = add_dynamic_network(&owner_hot, &owner_cold);
947+
948+
// Mark as *legacy*: registered_at < start_block
949+
let reg_at = NetworkRegisteredAt::<Test>::get(netuid);
950+
NetworkRegistrationStartBlock::<Test>::put(reg_at.saturating_add(1));
951+
952+
// Lock and (nonzero) emissions
953+
let lock_u64: u64 = 50_000;
954+
SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(lock_u64));
955+
Emission::<Test>::insert(
956+
netuid,
957+
vec![AlphaCurrency::from(1_500u64), AlphaCurrency::from(3_000u64)], // total 4_500 α
958+
);
959+
// Owner cut ≈ 50%
960+
SubnetOwnerCut::<Test>::put(32_768u16);
961+
962+
// Compute expected refund using the same math as the pallet
963+
let frac: U96F32 = SubtensorModule::get_float_subnet_owner_cut();
964+
let total_emitted_alpha: u64 = 1_500 + 3_000; // 4_500 α
965+
let owner_alpha_u64: u64 = U96F32::from_num(total_emitted_alpha)
966+
.saturating_mul(frac)
967+
.floor()
968+
.saturating_to_num::<u64>();
969+
970+
// Prefer sim_swap; fall back to current price if unavailable.
971+
let owner_emission_tao_u64: u64 = <Test as pallet::Config>::SwapInterface::sim_swap(
972+
netuid.into(),
973+
OrderType::Sell,
974+
owner_alpha_u64,
975+
)
976+
.map(|res| res.amount_paid_out)
977+
.unwrap_or_else(|_| {
978+
let price: U96F32 =
979+
<Test as pallet::Config>::SwapInterface::current_alpha_price(netuid.into());
980+
U96F32::from_num(owner_alpha_u64)
981+
.saturating_mul(price)
982+
.floor()
983+
.saturating_to_num::<u64>()
984+
});
985+
986+
let expected_refund: u64 = lock_u64.saturating_sub(owner_emission_tao_u64);
987+
988+
// Balances before
989+
let owner_before = SubtensorModule::get_coldkey_balance(&owner_cold);
990+
991+
// Run the path under test
992+
assert_ok!(SubtensorModule::destroy_alpha_in_out_stakes(netuid));
993+
994+
// Owner received their refund…
995+
let owner_after = SubtensorModule::get_coldkey_balance(&owner_cold);
996+
assert_eq!(owner_after, owner_before + expected_refund);
997+
998+
// …and the lock is always cleared to zero by destroy_alpha_in_out_stakes.
999+
assert_eq!(
1000+
SubtensorModule::get_subnet_locked_balance(netuid),
1001+
TaoCurrency::from(0u64)
1002+
);
1003+
});
1004+
1005+
// ──────────────────────────────────────────────────────────────────────
1006+
// Case B: NON‑LEGACY subnet → NO refund;
1007+
// ──────────────────────────────────────────────────────────────────────
1008+
new_test_ext(0).execute_with(|| {
1009+
// Owner + subnet
1010+
let owner_cold = U256::from(1_111);
1011+
let owner_hot = U256::from(2_222);
1012+
let netuid = add_dynamic_network(&owner_hot, &owner_cold);
1013+
1014+
// Explicitly set start_block <= registered_at to make it non‑legacy.
1015+
let reg_at = NetworkRegisteredAt::<Test>::get(netuid);
1016+
NetworkRegistrationStartBlock::<Test>::put(reg_at);
1017+
1018+
// Lock and emissions present (should be ignored for refund)
1019+
let lock_u64: u64 = 42_000;
1020+
SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(lock_u64));
1021+
Emission::<Test>::insert(netuid, vec![AlphaCurrency::from(5_000u64)]);
1022+
SubnetOwnerCut::<Test>::put(32_768u16); // ~50%
1023+
1024+
// Balances before
1025+
let owner_before = SubtensorModule::get_coldkey_balance(&owner_cold);
1026+
1027+
// Run the path under test
1028+
assert_ok!(SubtensorModule::destroy_alpha_in_out_stakes(netuid));
1029+
1030+
// No refund for non‑legacy
1031+
let owner_after = SubtensorModule::get_coldkey_balance(&owner_cold);
1032+
assert_eq!(owner_after, owner_before);
1033+
1034+
// Lock is still cleared to zero by the routine
1035+
assert_eq!(
1036+
SubtensorModule::get_subnet_locked_balance(netuid),
1037+
TaoCurrency::from(0u64)
1038+
);
1039+
});
1040+
1041+
// ──────────────────────────────────────────────────────────────────────
1042+
// Case C: LEGACY subnet but lock = 0 → no refund;
1043+
// ──────────────────────────────────────────────────────────────────────
1044+
new_test_ext(0).execute_with(|| {
1045+
// Owner + subnet
1046+
let owner_cold = U256::from(9_999);
1047+
let owner_hot = U256::from(8_888);
1048+
let netuid = add_dynamic_network(&owner_hot, &owner_cold);
1049+
1050+
// Mark as *legacy*
1051+
let reg_at = NetworkRegisteredAt::<Test>::get(netuid);
1052+
NetworkRegistrationStartBlock::<Test>::put(reg_at.saturating_add(1));
1053+
1054+
// lock = 0; emissions present (must not matter)
1055+
SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(0u64));
1056+
Emission::<Test>::insert(netuid, vec![AlphaCurrency::from(10_000u64)]);
1057+
SubnetOwnerCut::<Test>::put(32_768u16); // ~50%
1058+
1059+
let owner_before = SubtensorModule::get_coldkey_balance(&owner_cold);
1060+
assert_ok!(SubtensorModule::destroy_alpha_in_out_stakes(netuid));
1061+
let owner_after = SubtensorModule::get_coldkey_balance(&owner_cold);
1062+
1063+
// No refund possible when lock = 0
1064+
assert_eq!(owner_after, owner_before);
1065+
assert_eq!(
1066+
SubtensorModule::get_subnet_locked_balance(netuid),
1067+
TaoCurrency::from(0u64)
1068+
);
1069+
});
1070+
}
1071+
9171072
#[test]
9181073
fn prune_none_with_no_networks() {
9191074
new_test_ext(0).execute_with(|| {

0 commit comments

Comments
 (0)