Skip to content

Commit 0c5eaec

Browse files
committed
add migration and test
1 parent c55b226 commit 0c5eaec

File tree

4 files changed

+207
-1
lines changed

4 files changed

+207
-1
lines changed

pallets/subtensor/src/macros/hooks.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ mod hooks {
7676
// Migrate to RAO
7777
.saturating_add(migrations::migrate_rao::migrate_rao::<T>())
7878
// Fix the IsNetworkMember map to be consistent with other storage maps
79-
.saturating_add(migrations::migrate_fix_is_network_member::migrate_fix_is_network_member::<T>());
79+
.saturating_add(migrations::migrate_fix_is_network_member::migrate_fix_is_network_member::<T>())
80+
// Upgrade identities to V2
81+
.saturating_add(migrations::migrate_identities_v2::migrate_identities_to_v2::<T>());
8082
weight
8183
}
8284

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use super::*;
2+
use frame_support::weights::Weight;
3+
use log;
4+
use scale_info::prelude::{string::String, vec::Vec};
5+
6+
pub fn migrate_identities_to_v2<T: Config>() -> Weight {
7+
use frame_support::traits::Get;
8+
let migration_name = b"migrate_identities_to_v2".to_vec();
9+
10+
// Start counting weight
11+
let mut weight = T::DbWeight::get().reads(1);
12+
13+
// Check if we already ran this migration
14+
if HasMigrationRun::<T>::get(&migration_name) {
15+
log::info!(
16+
target: "runtime",
17+
"Migration '{:?}' has already run. Skipping.",
18+
String::from_utf8_lossy(&migration_name)
19+
);
20+
return weight;
21+
}
22+
23+
log::info!(
24+
target: "runtime",
25+
"Running migration '{}'",
26+
String::from_utf8_lossy(&migration_name)
27+
);
28+
29+
// -----------------------------
30+
// 1) Migrate Chain Identities
31+
// -----------------------------
32+
let old_identities = Identities::<T>::iter().collect::<Vec<_>>();
33+
for (account_id, old_identity) in old_identities.clone() {
34+
let new_identity = ChainIdentityV2 {
35+
name: old_identity.name,
36+
url: old_identity.url,
37+
github_repo: Vec::new(),
38+
image: old_identity.image,
39+
discord: old_identity.discord,
40+
description: old_identity.description,
41+
additional: old_identity.additional,
42+
};
43+
44+
// Insert into the new storage map
45+
IdentitiesV2::<T>::insert(&account_id, &new_identity);
46+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
47+
48+
Identities::<T>::remove(&account_id);
49+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
50+
}
51+
52+
weight = weight.saturating_add(T::DbWeight::get().reads(old_identities.len() as u64));
53+
54+
// -----------------------------
55+
// 2) Migrate Subnet Identities
56+
// -----------------------------
57+
let old_subnet_identities = SubnetIdentities::<T>::iter().collect::<Vec<_>>();
58+
for (netuid, old_subnet_identity) in old_subnet_identities.clone() {
59+
let new_subnet_identity = SubnetIdentityV2 {
60+
subnet_name: old_subnet_identity.subnet_name,
61+
github_repo: old_subnet_identity.github_repo,
62+
subnet_contact: old_subnet_identity.subnet_contact,
63+
subnet_url: Vec::new(),
64+
discord: Vec::new(),
65+
description: Vec::new(),
66+
additional: Vec::new(),
67+
};
68+
69+
// Insert into the new storage map
70+
SubnetIdentitiesV2::<T>::insert(netuid, &new_subnet_identity);
71+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
72+
73+
SubnetIdentities::<T>::remove(netuid);
74+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
75+
}
76+
weight = weight.saturating_add(T::DbWeight::get().reads(old_subnet_identities.len() as u64));
77+
78+
// -----------------------------
79+
// Mark the migration as done
80+
// -----------------------------
81+
HasMigrationRun::<T>::insert(&migration_name, true);
82+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
83+
84+
log::info!(
85+
target: "runtime",
86+
"Migration '{}' completed successfully.",
87+
String::from_utf8_lossy(&migration_name)
88+
);
89+
90+
weight
91+
}

pallets/subtensor/src/migrations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod migrate_delete_subnet_21;
66
pub mod migrate_delete_subnet_3;
77
pub mod migrate_fix_is_network_member;
88
pub mod migrate_fix_total_coldkey_stake;
9+
pub mod migrate_identities_v2;
910
pub mod migrate_init_total_issuance;
1011
pub mod migrate_populate_owned_hotkeys;
1112
pub mod migrate_populate_staking_hotkeys;

pallets/subtensor/src/tests/serving.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,118 @@ fn test_migrate_set_hotkey_identities() {
899899
});
900900
}
901901

902+
#[test]
903+
fn test_migrate_identities_to_v2() {
904+
new_test_ext(1).execute_with(|| {
905+
let account_id_1 = U256::from(1);
906+
let account_id_2 = U256::from(2);
907+
908+
let chainone_name = b"ChainOne".to_vec();
909+
let chainone_url = b"https://chainone.example".to_vec();
910+
let chainone_image = b"some_image_data".to_vec();
911+
let chainone_discord = b"discord#1".to_vec();
912+
let chainone_description = b"Old chain identity".to_vec();
913+
let chainone_additional = b"extra-info".to_vec();
914+
915+
let chaintwo_name = b"ChainTwo".to_vec();
916+
let chaintwo_url = b"https://chaintwo.example".to_vec();
917+
let chaintwo_description = b"Another chain identity".to_vec();
918+
919+
Identities::<Test>::insert(
920+
account_id_1,
921+
ChainIdentity {
922+
name: chainone_name.clone(),
923+
url: chainone_url.clone(),
924+
image: chainone_image.clone(),
925+
discord: chainone_discord.clone(),
926+
description: chainone_description.clone(),
927+
additional: chainone_additional.clone(),
928+
},
929+
);
930+
931+
Identities::<Test>::insert(
932+
account_id_2,
933+
ChainIdentity {
934+
name: chaintwo_name.clone(),
935+
url: chaintwo_url.clone(),
936+
image: b"".to_vec(),
937+
discord: b"".to_vec(),
938+
description: chaintwo_description.clone(),
939+
additional: b"".to_vec(),
940+
},
941+
);
942+
943+
let old_subnet_name = b"SubnetExample".to_vec();
944+
let old_github_repo = b"https://github.com/org/repo".to_vec();
945+
let old_subnet_contact = b"subnet@example".to_vec();
946+
947+
SubnetIdentities::<Test>::insert(
948+
42u16,
949+
SubnetIdentity {
950+
subnet_name: old_subnet_name.clone(),
951+
github_repo: old_github_repo.clone(),
952+
subnet_contact: old_subnet_contact.clone(),
953+
},
954+
);
955+
956+
assert!(Identities::<Test>::get(account_id_1).is_some());
957+
assert!(Identities::<Test>::get(account_id_2).is_some());
958+
assert!(SubnetIdentities::<Test>::get(42u16).is_some());
959+
assert!(!HasMigrationRun::<Test>::get(
960+
b"migrate_identities_to_v2".to_vec()
961+
));
962+
963+
let weight = crate::migrations::migrate_identities_v2::migrate_identities_to_v2::<Test>();
964+
965+
assert!(
966+
HasMigrationRun::<Test>::get(b"migrate_identities_to_v2".to_vec()),
967+
"Expected HasMigrationRun to be true after migration"
968+
);
969+
assert!(Identities::<Test>::get(account_id_1).is_none());
970+
assert!(Identities::<Test>::get(account_id_2).is_none());
971+
assert!(SubnetIdentities::<Test>::get(42u16).is_none());
972+
973+
let new_identity_1 = IdentitiesV2::<Test>::get(account_id_1)
974+
.expect("ChainOne should be migrated to IdentitiesV2");
975+
let expected_github_repo = b"".to_vec();
976+
977+
assert_eq!(new_identity_1.name, chainone_name);
978+
assert_eq!(new_identity_1.url, chainone_url);
979+
assert_eq!(new_identity_1.github_repo, expected_github_repo);
980+
assert_eq!(new_identity_1.image, chainone_image);
981+
assert_eq!(new_identity_1.discord, chainone_discord);
982+
assert_eq!(new_identity_1.description, chainone_description);
983+
assert_eq!(new_identity_1.additional, chainone_additional);
984+
985+
let new_identity_2 = IdentitiesV2::<Test>::get(account_id_2)
986+
.expect("ChainTwo should be migrated to IdentitiesV2");
987+
assert_eq!(new_identity_2.name, chaintwo_name);
988+
assert_eq!(new_identity_2.url, chaintwo_url);
989+
assert_eq!(new_identity_2.github_repo, b"".to_vec());
990+
991+
let new_subnet_identity = SubnetIdentitiesV2::<Test>::get(42u16)
992+
.expect("SubnetExample should be migrated to SubnetIdentitiesV2");
993+
994+
let expected_subnet_url = b"".to_vec();
995+
let expected_discord = b"".to_vec();
996+
let expected_description = b"".to_vec();
997+
let expected_additional = b"".to_vec();
998+
999+
assert_eq!(new_subnet_identity.subnet_name, old_subnet_name);
1000+
assert_eq!(new_subnet_identity.github_repo, old_github_repo);
1001+
assert_eq!(new_subnet_identity.subnet_contact, old_subnet_contact);
1002+
assert_eq!(new_subnet_identity.subnet_url, expected_subnet_url);
1003+
assert_eq!(new_subnet_identity.discord, expected_discord);
1004+
assert_eq!(new_subnet_identity.description, expected_description);
1005+
assert_eq!(new_subnet_identity.additional, expected_additional);
1006+
1007+
assert!(
1008+
weight != Weight::zero(),
1009+
"Migration weight should be non-zero"
1010+
);
1011+
});
1012+
}
1013+
9021014
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test serving -- test_do_set_subnet_identity --exact --nocapture
9031015
#[test]
9041016
fn test_do_set_subnet_identity() {

0 commit comments

Comments
 (0)