Skip to content

Commit aa521f4

Browse files
authored
Merge pull request #863 from opentensor/fix/hotkey-swap-parentkeys
Fix: Hotkey swap causes parent key to lose emissions from children
2 parents 517fabf + 0a34147 commit aa521f4

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

Diff for: pallets/subtensor/src/swap/swap_hotkey.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,20 @@ impl<T: Config> Pallet<T> {
325325
// Remove the old hotkey's child entries
326326
ChildKeys::<T>::remove(old_hotkey, netuid);
327327
// Insert the same child entries for the new hotkey
328-
ChildKeys::<T>::insert(new_hotkey, netuid, my_children);
328+
ChildKeys::<T>::insert(new_hotkey, netuid, my_children.clone());
329+
for (_, child_key_i) in my_children {
330+
// For each child, update their parent list
331+
let mut child_parents: Vec<(u64, T::AccountId)> =
332+
ParentKeys::<T>::get(child_key_i.clone(), netuid);
333+
for parent in child_parents.iter_mut() {
334+
// If the parent is the old hotkey, replace it with the new hotkey
335+
if parent.1 == *old_hotkey {
336+
parent.1 = new_hotkey.clone();
337+
}
338+
}
339+
// Update the child's parent list
340+
ParentKeys::<T>::insert(child_key_i, netuid, child_parents);
341+
}
329342
}
330343

331344
// 13. Swap ParentKeys.

Diff for: pallets/subtensor/tests/swap_hotkey.rs

+97
Original file line numberDiff line numberDiff line change
@@ -1204,3 +1204,100 @@ fn test_swap_hotkey_with_pending_emissions() {
12041204
assert!(!PendingdHotkeyEmission::<Test>::contains_key(old_hotkey));
12051205
});
12061206
}
1207+
1208+
#[test]
1209+
fn test_swap_parent_hotkey_childkey_maps() {
1210+
new_test_ext(1).execute_with(|| {
1211+
let netuid: u16 = 1;
1212+
let parent_old = U256::from(1);
1213+
let coldkey = U256::from(2);
1214+
let child = U256::from(3);
1215+
let parent_new = U256::from(4);
1216+
add_network(netuid, 0, 0);
1217+
SubtensorModule::create_account_if_non_existent(&coldkey, &parent_old);
1218+
1219+
// Set child and verify state maps
1220+
assert_ok!(SubtensorModule::do_set_children(
1221+
RuntimeOrigin::signed(coldkey),
1222+
parent_old,
1223+
netuid,
1224+
vec![(u64::MAX, child)]
1225+
));
1226+
assert_eq!(
1227+
ParentKeys::<Test>::get(child, netuid),
1228+
vec![(u64::MAX, parent_old)]
1229+
);
1230+
assert_eq!(
1231+
ChildKeys::<Test>::get(parent_old, netuid),
1232+
vec![(u64::MAX, child)]
1233+
);
1234+
1235+
// Swap
1236+
let mut weight = Weight::zero();
1237+
assert_ok!(SubtensorModule::perform_hotkey_swap(
1238+
&parent_old,
1239+
&parent_new,
1240+
&coldkey,
1241+
&mut weight
1242+
));
1243+
1244+
// Verify parent and child keys updates
1245+
assert_eq!(
1246+
ParentKeys::<Test>::get(child, netuid),
1247+
vec![(u64::MAX, parent_new)]
1248+
);
1249+
assert_eq!(
1250+
ChildKeys::<Test>::get(parent_new, netuid),
1251+
vec![(u64::MAX, child)]
1252+
);
1253+
})
1254+
}
1255+
1256+
#[test]
1257+
fn test_swap_child_hotkey_childkey_maps() {
1258+
new_test_ext(1).execute_with(|| {
1259+
let netuid: u16 = 1;
1260+
let parent = U256::from(1);
1261+
let coldkey = U256::from(2);
1262+
let child_old = U256::from(3);
1263+
let child_new = U256::from(4);
1264+
add_network(netuid, 0, 0);
1265+
SubtensorModule::create_account_if_non_existent(&coldkey, &child_old);
1266+
SubtensorModule::create_account_if_non_existent(&coldkey, &parent);
1267+
1268+
// Set child and verify state maps
1269+
assert_ok!(SubtensorModule::do_set_children(
1270+
RuntimeOrigin::signed(coldkey),
1271+
parent,
1272+
netuid,
1273+
vec![(u64::MAX, child_old)]
1274+
));
1275+
assert_eq!(
1276+
ParentKeys::<Test>::get(child_old, netuid),
1277+
vec![(u64::MAX, parent)]
1278+
);
1279+
assert_eq!(
1280+
ChildKeys::<Test>::get(parent, netuid),
1281+
vec![(u64::MAX, child_old)]
1282+
);
1283+
1284+
// Swap
1285+
let mut weight = Weight::zero();
1286+
assert_ok!(SubtensorModule::perform_hotkey_swap(
1287+
&child_old,
1288+
&child_new,
1289+
&coldkey,
1290+
&mut weight
1291+
));
1292+
1293+
// Verify parent and child keys updates
1294+
assert_eq!(
1295+
ParentKeys::<Test>::get(child_new, netuid),
1296+
vec![(u64::MAX, parent)]
1297+
);
1298+
assert_eq!(
1299+
ChildKeys::<Test>::get(parent, netuid),
1300+
vec![(u64::MAX, child_new)]
1301+
);
1302+
})
1303+
}

0 commit comments

Comments
 (0)