Skip to content

Commit ecd3612

Browse files
committed
add highly_concurrent test
1 parent 8d5de80 commit ecd3612

File tree

1 file changed

+279
-0
lines changed

1 file changed

+279
-0
lines changed

pallets/subtensor/tests/weights.rs

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use sp_runtime::{
1515
};
1616
use sp_std::collections::vec_deque::VecDeque;
1717
use substrate_fixed::types::I32F32;
18+
use scale_info::prelude::collections::HashMap;
1819

1920
/***************************
2021
pub fn set_weights() tests
@@ -3675,3 +3676,281 @@ fn test_batch_reveal_with_out_of_order_commits() {
36753676
assert!(commits.is_none());
36763677
});
36773678
}
3679+
3680+
#[test]
3681+
fn test_highly_concurrent_commits_and_reveals_with_multiple_hotkeys() {
3682+
new_test_ext(1).execute_with(|| {
3683+
// ==== Test Configuration ====
3684+
let netuid: u16 = 1;
3685+
let num_hotkeys: usize = 10;
3686+
let max_unrevealed_commits: usize = 10;
3687+
let commits_per_hotkey: usize = 20;
3688+
let initial_reveal_period: u64 = 5;
3689+
let initial_tempo: u16 = 100;
3690+
3691+
// ==== Setup Network ====
3692+
add_network(netuid, initial_tempo, 0);
3693+
SubtensorModule::set_commit_reveal_weights_enabled(netuid, true);
3694+
SubtensorModule::set_weights_set_rate_limit(netuid, 0);
3695+
SubtensorModule::set_reveal_period(netuid, initial_reveal_period);
3696+
SubtensorModule::set_max_registrations_per_block(netuid, u16::MAX);
3697+
SubtensorModule::set_target_registrations_per_interval(netuid, u16::MAX);
3698+
3699+
// ==== Register Validators ====
3700+
for uid in 0..5 {
3701+
let validator_id = U256::from(100 + uid as u64);
3702+
register_ok_neuron(netuid, validator_id, U256::from(200 + uid as u64), 300_000);
3703+
SubtensorModule::set_validator_permit_for_uid(netuid, uid, true);
3704+
}
3705+
3706+
// ==== Register Hotkeys ====
3707+
let mut hotkeys: Vec<<Test as frame_system::Config>::AccountId> = Vec::new();
3708+
for i in 0..num_hotkeys {
3709+
let hotkey_id = U256::from(1000 + i as u64);
3710+
register_ok_neuron(netuid, hotkey_id, U256::from(2000 + i as u64), 100_000);
3711+
hotkeys.push(hotkey_id);
3712+
}
3713+
3714+
// ==== Initialize Commit Information ====
3715+
let mut commit_info_map: HashMap<
3716+
<Test as frame_system::Config>::AccountId,
3717+
Vec<(H256, Vec<u16>, Vec<u16>, Vec<u16>, u64)>,
3718+
> = HashMap::new();
3719+
3720+
// Initialize the map
3721+
for hotkey in &hotkeys {
3722+
commit_info_map.insert(*hotkey, Vec::new());
3723+
}
3724+
3725+
// ==== Function to Generate Unique Data ====
3726+
fn generate_unique_data(index: usize) -> (Vec<u16>, Vec<u16>, Vec<u16>, u64) {
3727+
let uids = vec![index as u16, (index + 1) as u16];
3728+
let values = vec![(index * 10) as u16, ((index + 1) * 10) as u16];
3729+
let salt = vec![(index % 100) as u16; 8];
3730+
let version_key = index as u64;
3731+
(uids, values, salt, version_key)
3732+
}
3733+
3734+
// ==== Simulate Concurrent Commits and Reveals ====
3735+
for i in 0..commits_per_hotkey {
3736+
for hotkey in &hotkeys {
3737+
3738+
let current_commits = pallet_subtensor::WeightCommits::<Test>::get(netuid, hotkey)
3739+
.unwrap_or_default();
3740+
if current_commits.len() >= max_unrevealed_commits {
3741+
continue;
3742+
}
3743+
3744+
let (uids, values, salt, version_key) = generate_unique_data(i);
3745+
let commit_hash: H256 = BlakeTwo256::hash_of(&(
3746+
*hotkey,
3747+
netuid,
3748+
uids.clone(),
3749+
values.clone(),
3750+
salt.clone(),
3751+
version_key,
3752+
));
3753+
3754+
if let Some(commits) = commit_info_map.get_mut(hotkey) {
3755+
commits.push((commit_hash, salt.clone(), uids.clone(), values.clone(), version_key));
3756+
}
3757+
3758+
assert_ok!(SubtensorModule::commit_weights(
3759+
RuntimeOrigin::signed(*hotkey),
3760+
netuid,
3761+
commit_hash
3762+
));
3763+
}
3764+
3765+
// ==== Reveal Phase ====
3766+
for hotkey in &hotkeys {
3767+
if let Some(commits) = commit_info_map.get_mut(hotkey) {
3768+
if commits.is_empty() {
3769+
continue; // No commits to reveal
3770+
}
3771+
3772+
let (_commit_hash, salt, uids, values, version_key) = commits.first().expect("expected a value");
3773+
3774+
let reveal_result = SubtensorModule::reveal_weights(
3775+
RuntimeOrigin::signed(*hotkey),
3776+
netuid,
3777+
uids.clone(),
3778+
values.clone(),
3779+
salt.clone(),
3780+
*version_key,
3781+
);
3782+
3783+
match reveal_result {
3784+
Ok(_) => {
3785+
commits.remove(0);
3786+
}
3787+
Err(e) => {
3788+
if e == Error::<Test>::RevealTooEarly.into()
3789+
|| e == Error::<Test>::ExpiredWeightCommit.into()
3790+
|| e == Error::<Test>::InvalidRevealCommitHashNotMatch.into()
3791+
{
3792+
log::info!("Expected error during reveal after epoch advancement: {:?}", e);
3793+
} else {
3794+
panic!(
3795+
"Unexpected error during reveal: {:?}, expected RevealTooEarly, ExpiredWeightCommit, or InvalidRevealCommitHashNotMatch",
3796+
e
3797+
);
3798+
}
3799+
}
3800+
}
3801+
}
3802+
}
3803+
}
3804+
3805+
// ==== Modify Network Parameters During Commits ====
3806+
SubtensorModule::set_tempo(netuid, 150);
3807+
SubtensorModule::set_reveal_period(netuid, 7);
3808+
log::info!("Changed tempo to 150 and reveal_period to 7 during commits.");
3809+
3810+
step_epochs(3, netuid);
3811+
3812+
// ==== Continue Reveals After Epoch Advancement ====
3813+
for hotkey in &hotkeys {
3814+
if let Some(commits) = commit_info_map.get_mut(hotkey) {
3815+
while !commits.is_empty() {
3816+
let (_commit_hash, salt, uids, values, version_key) = &commits[0];
3817+
3818+
// Attempt to reveal
3819+
let reveal_result = SubtensorModule::reveal_weights(
3820+
RuntimeOrigin::signed(*hotkey),
3821+
netuid,
3822+
uids.clone(),
3823+
values.clone(),
3824+
salt.clone(),
3825+
*version_key,
3826+
);
3827+
3828+
match reveal_result {
3829+
Ok(_) => {
3830+
commits.remove(0);
3831+
}
3832+
Err(e) => {
3833+
// Check if the error is due to reveal being too early or commit expired
3834+
if e == Error::<Test>::RevealTooEarly.into()
3835+
|| e == Error::<Test>::ExpiredWeightCommit.into()
3836+
|| e == Error::<Test>::InvalidRevealCommitHashNotMatch.into()
3837+
{
3838+
log::info!("Expected error during reveal after epoch advancement: {:?}", e);
3839+
break;
3840+
} else {
3841+
panic!(
3842+
"Unexpected error during reveal after epoch advancement: {:?}, expected RevealTooEarly, ExpiredWeightCommit, or InvalidRevealCommitHashNotMatch",
3843+
e
3844+
);
3845+
}
3846+
}
3847+
}
3848+
}
3849+
}
3850+
}
3851+
3852+
// ==== Change Network Parameters Again ====
3853+
SubtensorModule::set_tempo(netuid, 200);
3854+
SubtensorModule::set_reveal_period(netuid, 10);
3855+
log::info!("Changed tempo to 200 and reveal_period to 10 after initial reveals.");
3856+
3857+
step_epochs(10, netuid);
3858+
3859+
// ==== Final Reveal Attempts ====
3860+
for (hotkey, commits) in commit_info_map.iter_mut() {
3861+
for (_commit_hash, salt, uids, values, version_key) in commits.iter() {
3862+
let reveal_result = SubtensorModule::reveal_weights(
3863+
RuntimeOrigin::signed(*hotkey),
3864+
netuid,
3865+
uids.clone(),
3866+
values.clone(),
3867+
salt.clone(),
3868+
*version_key,
3869+
);
3870+
3871+
assert_eq!(
3872+
reveal_result,
3873+
Err(Error::<Test>::ExpiredWeightCommit.into()),
3874+
"Expected ExpiredWeightCommit error, got {:?}",
3875+
reveal_result
3876+
);
3877+
}
3878+
}
3879+
3880+
for hotkey in &hotkeys {
3881+
commit_info_map.insert(*hotkey, Vec::new());
3882+
3883+
for i in 0..max_unrevealed_commits {
3884+
let (uids, values, salt, version_key) = generate_unique_data(i + commits_per_hotkey);
3885+
let commit_hash: H256 = BlakeTwo256::hash_of(&(
3886+
*hotkey,
3887+
netuid,
3888+
uids.clone(),
3889+
values.clone(),
3890+
salt.clone(),
3891+
version_key,
3892+
));
3893+
3894+
assert_ok!(SubtensorModule::commit_weights(
3895+
RuntimeOrigin::signed(*hotkey),
3896+
netuid,
3897+
commit_hash
3898+
));
3899+
}
3900+
3901+
let (uids, values, salt, version_key) = generate_unique_data(max_unrevealed_commits + commits_per_hotkey);
3902+
let commit_hash: H256 = BlakeTwo256::hash_of(&(
3903+
*hotkey,
3904+
netuid,
3905+
uids.clone(),
3906+
values.clone(),
3907+
salt.clone(),
3908+
version_key,
3909+
));
3910+
3911+
assert_err!(
3912+
SubtensorModule::commit_weights(
3913+
RuntimeOrigin::signed(*hotkey),
3914+
netuid,
3915+
commit_hash
3916+
),
3917+
Error::<Test>::TooManyUnrevealedCommits
3918+
);
3919+
}
3920+
3921+
// Attempt unauthorized reveal
3922+
let unauthorized_hotkey = hotkeys[0];
3923+
let target_hotkey = hotkeys[1];
3924+
if let Some(commits) = commit_info_map.get(&target_hotkey) {
3925+
if let Some((_commit_hash, salt, uids, values, version_key)) = commits.first() {
3926+
assert_err!(
3927+
SubtensorModule::reveal_weights(
3928+
RuntimeOrigin::signed(unauthorized_hotkey),
3929+
netuid,
3930+
uids.clone(),
3931+
values.clone(),
3932+
salt.clone(),
3933+
*version_key,
3934+
),
3935+
Error::<Test>::InvalidRevealCommitHashNotMatch
3936+
);
3937+
}
3938+
}
3939+
3940+
let non_committing_hotkey: <Test as frame_system::Config>::AccountId = U256::from(9999);
3941+
assert_err!(
3942+
SubtensorModule::reveal_weights(
3943+
RuntimeOrigin::signed(non_committing_hotkey),
3944+
netuid,
3945+
vec![0, 1],
3946+
vec![10, 20],
3947+
vec![0; 8],
3948+
0,
3949+
),
3950+
Error::<Test>::NoWeightsCommitFound
3951+
);
3952+
3953+
assert_eq!(SubtensorModule::get_reveal_period(netuid), 10);
3954+
assert_eq!(SubtensorModule::get_tempo(netuid), 200);
3955+
})
3956+
}

0 commit comments

Comments
 (0)