Skip to content

Commit beadf9f

Browse files
committed
add missing validate tests
1 parent 826e55c commit beadf9f

File tree

2 files changed

+169
-5
lines changed

2 files changed

+169
-5
lines changed

pallets/subtensor/tests/root.rs

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#![allow(clippy::indexing_slicing, clippy::unwrap_used)]
22

33
use crate::mock::*;
4-
use frame_support::{assert_err, assert_ok};
5-
use frame_system::Config;
6-
use frame_system::{EventRecord, Phase};
7-
use pallet_subtensor::migration;
8-
use pallet_subtensor::Error;
4+
use frame_support::{assert_err, assert_ok, dispatch::DispatchInfo};
5+
use frame_system::{Config, EventRecord, Phase};
6+
use pallet_subtensor::{
7+
migration, BaseDifficulty, ColdkeySwapDestinations, Error, MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP,
8+
};
99
use sp_core::{Get, H256, U256};
10+
use sp_runtime::{
11+
traits::{DispatchInfoOf, SignedExtension},
12+
transaction_validity::{InvalidTransaction, TransactionValidityError},
13+
};
1014

1115
mod mock;
1216

@@ -974,3 +978,103 @@ fn test_dissolve_network_does_not_exist_err() {
974978
);
975979
});
976980
}
981+
982+
#[test]
983+
fn test_dissolve_network_validate() {
984+
fn generate_valid_pow(coldkey: &U256, block_number: u64, difficulty: U256) -> (H256, u64) {
985+
let mut nonce: u64 = 0;
986+
loop {
987+
let work = SubtensorModule::create_seal_hash(block_number, nonce, coldkey);
988+
if SubtensorModule::hash_meets_difficulty(&work, difficulty) {
989+
return (work, nonce);
990+
}
991+
nonce += 1;
992+
}
993+
}
994+
// Testing the signed extension validate function
995+
// correctly filters the `dissolve_network` transaction.
996+
997+
new_test_ext(0).execute_with(|| {
998+
let netuid: u16 = 1;
999+
let delegate_coldkey = U256::from(1);
1000+
let delegate_hotkey = U256::from(2);
1001+
let new_coldkey = U256::from(3);
1002+
let current_block = 0u64;
1003+
1004+
add_network(netuid, 0, 0);
1005+
register_ok_neuron(netuid, delegate_hotkey, delegate_coldkey, 0);
1006+
1007+
// Make delegate a delegate
1008+
assert_ok!(SubtensorModule::become_delegate(
1009+
RuntimeOrigin::signed(delegate_coldkey),
1010+
delegate_hotkey
1011+
));
1012+
1013+
// Add more than 500 TAO of stake to the delegate's hotkey
1014+
let stake_amount = 501_000_000_000; // 501 TAO in RAO
1015+
let delegator = U256::from(4);
1016+
SubtensorModule::add_balance_to_coldkey_account(&delegator, stake_amount);
1017+
assert_ok!(SubtensorModule::add_stake(
1018+
RuntimeOrigin::signed(delegator),
1019+
delegate_hotkey,
1020+
stake_amount
1021+
));
1022+
1023+
// Ensure the delegate's coldkey has less than minimum balance
1024+
assert!(
1025+
SubtensorModule::get_coldkey_balance(&delegate_coldkey)
1026+
< MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP,
1027+
"Delegate coldkey balance should be less than minimum required"
1028+
);
1029+
1030+
// Ensure the delegate's hotkey has more than 500 TAO delegated
1031+
assert!(
1032+
SubtensorModule::get_total_delegated_stake(&delegate_coldkey) >= 500_000_000_000,
1033+
"Delegate hotkey should have at least 500 TAO delegated"
1034+
);
1035+
1036+
// Generate valid PoW
1037+
let (work, nonce) = generate_valid_pow(
1038+
&delegate_coldkey,
1039+
current_block,
1040+
U256::from(4) * U256::from(BaseDifficulty::<Test>::get()),
1041+
);
1042+
1043+
// Schedule coldkey swap
1044+
assert_ok!(SubtensorModule::do_schedule_coldkey_swap(
1045+
&delegate_coldkey,
1046+
&new_coldkey,
1047+
work.to_fixed_bytes().to_vec(),
1048+
current_block,
1049+
nonce,
1050+
));
1051+
1052+
// Verify that the swap was scheduled
1053+
assert_eq!(
1054+
ColdkeySwapDestinations::<Test>::get(delegate_coldkey),
1055+
vec![new_coldkey]
1056+
);
1057+
1058+
// Check if the coldkey is in arbitration
1059+
assert!(
1060+
SubtensorModule::coldkey_in_arbitration(&delegate_coldkey),
1061+
"Delegate coldkey should be in arbitration after swap"
1062+
);
1063+
1064+
let who = delegate_coldkey; // The coldkey signs this transaction
1065+
let call = RuntimeCall::SubtensorModule(SubtensorCall::dissolve_network { netuid });
1066+
1067+
let info: DispatchInfo =
1068+
DispatchInfoOf::<<Test as frame_system::Config>::RuntimeCall>::default();
1069+
1070+
let extension = pallet_subtensor::SubtensorSignedExtension::<Test>::new();
1071+
1072+
// Submit to the signed extension validate function
1073+
let result_in_arbitration = extension.validate(&who, &call.clone(), &info, 10);
1074+
// Should fail with InvalidTransaction::Custom(6) because coldkey is in arbitration
1075+
assert_err!(
1076+
result_in_arbitration,
1077+
TransactionValidityError::Invalid(InvalidTransaction::Custom(6))
1078+
);
1079+
});
1080+
}

pallets/subtensor/tests/weights.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,66 @@ fn test_reveal_weights_dispatch_info_ok() {
259259
});
260260
}
261261

262+
#[test]
263+
fn test_set_weights_validate() {
264+
// Testing the signed extension validate function
265+
// correctly filters the `set_weights` transaction.
266+
267+
new_test_ext(0).execute_with(|| {
268+
let netuid: u16 = 1;
269+
let coldkey = U256::from(0);
270+
let hotkey: U256 = U256::from(1);
271+
assert_ne!(hotkey, coldkey);
272+
273+
let who = hotkey; // The hotkey signs this transaction
274+
275+
let call = RuntimeCall::SubtensorModule(SubtensorCall::set_weights {
276+
netuid,
277+
dests: vec![1, 1],
278+
weights: vec![1, 1],
279+
version_key: 0,
280+
});
281+
282+
// Create netuid
283+
add_network(netuid, 0, 0);
284+
// Register the hotkey
285+
SubtensorModule::append_neuron(netuid, &hotkey, 0);
286+
Owner::<Test>::insert(hotkey, coldkey);
287+
288+
let min_stake = 500_000_000_000;
289+
// Set the minimum stake
290+
SubtensorModule::set_weights_min_stake(min_stake);
291+
292+
// Verify stake is less than minimum
293+
assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake);
294+
let info: DispatchInfo =
295+
DispatchInfoOf::<<Test as frame_system::Config>::RuntimeCall>::default();
296+
297+
let extension = pallet_subtensor::SubtensorSignedExtension::<Test>::new();
298+
// Submit to the signed extension validate function
299+
let result_no_stake = extension.validate(&who, &call.clone(), &info, 10);
300+
// Should fail due to insufficient stake
301+
assert_err!(
302+
result_no_stake,
303+
TransactionValidityError::Invalid(InvalidTransaction::Custom(3))
304+
);
305+
306+
// Increase the stake to be equal to the minimum
307+
SubtensorModule::increase_stake_on_hotkey_account(&hotkey, min_stake);
308+
309+
// Verify stake is equal to minimum
310+
assert_eq!(
311+
SubtensorModule::get_total_stake_for_hotkey(&hotkey),
312+
min_stake
313+
);
314+
315+
// Submit to the signed extension validate function
316+
let result_min_stake = extension.validate(&who, &call.clone(), &info, 10);
317+
// Now the call should pass
318+
assert_ok!(result_min_stake);
319+
});
320+
}
321+
262322
#[test]
263323
fn test_reveal_weights_validate() {
264324
// Testing the signed extension validate function

0 commit comments

Comments
 (0)