@@ -9,6 +9,7 @@ use mock::*;
99use pallet_subtensor:: * ;
1010use sp_core:: H256 ;
1111use sp_core:: U256 ;
12+ use sp_runtime:: SaturatedConversion ;
1213
1314// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner --exact --nocapture
1415#[ test]
@@ -1148,3 +1149,188 @@ fn test_swap_complex_parent_child_structure() {
11481149 ) ;
11491150 } ) ;
11501151}
1152+
1153+ // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_hotkey_swap_stake_delta --exact --nocapture
1154+ #[ test]
1155+ fn test_hotkey_swap_stake_delta ( ) {
1156+ new_test_ext ( 1 ) . execute_with ( || {
1157+ let old_hotkey = U256 :: from ( 3 ) ;
1158+ let new_hotkey = U256 :: from ( 4 ) ;
1159+ let coldkey = U256 :: from ( 7 ) ;
1160+
1161+ let coldkeys = [ U256 :: from ( 1 ) , U256 :: from ( 2 ) , U256 :: from ( 5 ) ] ;
1162+
1163+ let mut weight = Weight :: zero ( ) ;
1164+
1165+ // Set up initial state
1166+ // Add stake delta for each coldkey and the old_hotkey
1167+ for & coldkey in coldkeys. iter ( ) {
1168+ StakeDeltaSinceLastEmissionDrain :: < Test > :: insert (
1169+ old_hotkey,
1170+ coldkey,
1171+ ( 123 + coldkey. saturated_into :: < i128 > ( ) ) ,
1172+ ) ;
1173+
1174+ StakingHotkeys :: < Test > :: insert ( coldkey, vec ! [ old_hotkey] ) ;
1175+ }
1176+
1177+ // Add stake delta for one coldkey and the new_hotkey
1178+ StakeDeltaSinceLastEmissionDrain :: < Test > :: insert ( new_hotkey, coldkeys[ 0 ] , 456 ) ;
1179+ // Add corresponding StakingHotkeys
1180+ StakingHotkeys :: < Test > :: insert ( coldkeys[ 0 ] , vec ! [ old_hotkey, new_hotkey] ) ;
1181+
1182+ // Perform the swap
1183+ SubtensorModule :: perform_hotkey_swap ( & old_hotkey, & new_hotkey, & coldkey, & mut weight) ;
1184+
1185+ // Ensure the stake delta is correctly transferred for each coldkey
1186+ // -- coldkey[0] maintains its stake delta from the new_hotkey and the old_hotkey
1187+ assert_eq ! (
1188+ StakeDeltaSinceLastEmissionDrain :: <Test >:: get( new_hotkey, coldkeys[ 0 ] ) ,
1189+ 123 + coldkeys[ 0 ] . saturated_into:: <i128 >( ) + 456
1190+ ) ;
1191+ // -- coldkey[1..] maintains its stake delta from the old_hotkey
1192+ for & coldkey in coldkeys[ 1 ..] . iter ( ) {
1193+ assert_eq ! (
1194+ StakeDeltaSinceLastEmissionDrain :: <Test >:: get( new_hotkey, coldkey) ,
1195+ 123 + coldkey. saturated_into:: <i128 >( )
1196+ ) ;
1197+ assert ! ( !StakeDeltaSinceLastEmissionDrain :: <Test >:: contains_key(
1198+ old_hotkey, coldkey
1199+ ) ) ;
1200+ }
1201+ } ) ;
1202+ }
1203+
1204+ // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_pending_emissions --exact --nocapture
1205+ #[ test]
1206+ fn test_swap_hotkey_with_pending_emissions ( ) {
1207+ new_test_ext ( 1 ) . execute_with ( || {
1208+ let old_hotkey = U256 :: from ( 1 ) ;
1209+ let new_hotkey = U256 :: from ( 2 ) ;
1210+ let coldkey = U256 :: from ( 3 ) ;
1211+ let netuid = 0u16 ;
1212+ let mut weight = Weight :: zero ( ) ;
1213+
1214+ let pending_emission = 123_456_789u64 ;
1215+
1216+ // Set up initial state
1217+ add_network ( netuid, 0 , 1 ) ;
1218+
1219+ // Set up pending emissions
1220+ PendingdHotkeyEmission :: < Test > :: insert ( old_hotkey, pending_emission) ;
1221+ // Verify the pending emissions are set
1222+ assert_eq ! (
1223+ PendingdHotkeyEmission :: <Test >:: get( old_hotkey) ,
1224+ pending_emission
1225+ ) ;
1226+ // Verify the new hotkey does not have any pending emissions
1227+ assert ! ( !PendingdHotkeyEmission :: <Test >:: contains_key( new_hotkey) ) ;
1228+
1229+ // Perform the swap
1230+ SubtensorModule :: perform_hotkey_swap ( & old_hotkey, & new_hotkey, & coldkey, & mut weight) ;
1231+
1232+ // Verify the pending emissions are transferred
1233+ assert_eq ! (
1234+ PendingdHotkeyEmission :: <Test >:: get( new_hotkey) ,
1235+ pending_emission
1236+ ) ;
1237+ assert ! ( !PendingdHotkeyEmission :: <Test >:: contains_key( old_hotkey) ) ;
1238+ } ) ;
1239+ }
1240+
1241+ #[ test]
1242+ fn test_swap_parent_hotkey_childkey_maps ( ) {
1243+ new_test_ext ( 1 ) . execute_with ( || {
1244+ let netuid: u16 = 1 ;
1245+ let parent_old = U256 :: from ( 1 ) ;
1246+ let coldkey = U256 :: from ( 2 ) ;
1247+ let child = U256 :: from ( 3 ) ;
1248+ let parent_new = U256 :: from ( 4 ) ;
1249+ add_network ( netuid, 0 , 0 ) ;
1250+ SubtensorModule :: create_account_if_non_existent ( & coldkey, & parent_old) ;
1251+
1252+ // Set child and verify state maps
1253+ assert_ok ! ( SubtensorModule :: do_set_children(
1254+ RuntimeOrigin :: signed( coldkey) ,
1255+ parent_old,
1256+ netuid,
1257+ vec![ ( u64 :: MAX , child) ]
1258+ ) ) ;
1259+ assert_eq ! (
1260+ ParentKeys :: <Test >:: get( child, netuid) ,
1261+ vec![ ( u64 :: MAX , parent_old) ]
1262+ ) ;
1263+ assert_eq ! (
1264+ ChildKeys :: <Test >:: get( parent_old, netuid) ,
1265+ vec![ ( u64 :: MAX , child) ]
1266+ ) ;
1267+
1268+ // Swap
1269+ let mut weight = Weight :: zero ( ) ;
1270+ assert_ok ! ( SubtensorModule :: perform_hotkey_swap(
1271+ & parent_old,
1272+ & parent_new,
1273+ & coldkey,
1274+ & mut weight
1275+ ) ) ;
1276+
1277+ // Verify parent and child keys updates
1278+ assert_eq ! (
1279+ ParentKeys :: <Test >:: get( child, netuid) ,
1280+ vec![ ( u64 :: MAX , parent_new) ]
1281+ ) ;
1282+ assert_eq ! (
1283+ ChildKeys :: <Test >:: get( parent_new, netuid) ,
1284+ vec![ ( u64 :: MAX , child) ]
1285+ ) ;
1286+ } )
1287+ }
1288+
1289+ #[ test]
1290+ fn test_swap_child_hotkey_childkey_maps ( ) {
1291+ new_test_ext ( 1 ) . execute_with ( || {
1292+ let netuid: u16 = 1 ;
1293+ let parent = U256 :: from ( 1 ) ;
1294+ let coldkey = U256 :: from ( 2 ) ;
1295+ let child_old = U256 :: from ( 3 ) ;
1296+ let child_new = U256 :: from ( 4 ) ;
1297+ add_network ( netuid, 0 , 0 ) ;
1298+ SubtensorModule :: create_account_if_non_existent ( & coldkey, & child_old) ;
1299+ SubtensorModule :: create_account_if_non_existent ( & coldkey, & parent) ;
1300+
1301+ // Set child and verify state maps
1302+ assert_ok ! ( SubtensorModule :: do_set_children(
1303+ RuntimeOrigin :: signed( coldkey) ,
1304+ parent,
1305+ netuid,
1306+ vec![ ( u64 :: MAX , child_old) ]
1307+ ) ) ;
1308+ assert_eq ! (
1309+ ParentKeys :: <Test >:: get( child_old, netuid) ,
1310+ vec![ ( u64 :: MAX , parent) ]
1311+ ) ;
1312+ assert_eq ! (
1313+ ChildKeys :: <Test >:: get( parent, netuid) ,
1314+ vec![ ( u64 :: MAX , child_old) ]
1315+ ) ;
1316+
1317+ // Swap
1318+ let mut weight = Weight :: zero ( ) ;
1319+ assert_ok ! ( SubtensorModule :: perform_hotkey_swap(
1320+ & child_old,
1321+ & child_new,
1322+ & coldkey,
1323+ & mut weight
1324+ ) ) ;
1325+
1326+ // Verify parent and child keys updates
1327+ assert_eq ! (
1328+ ParentKeys :: <Test >:: get( child_new, netuid) ,
1329+ vec![ ( u64 :: MAX , parent) ]
1330+ ) ;
1331+ assert_eq ! (
1332+ ChildKeys :: <Test >:: get( parent, netuid) ,
1333+ vec![ ( u64 :: MAX , child_new) ]
1334+ ) ;
1335+ } )
1336+ }
0 commit comments