@@ -9,6 +9,7 @@ use mock::*;
9
9
use pallet_subtensor:: * ;
10
10
use sp_core:: H256 ;
11
11
use sp_core:: U256 ;
12
+ use sp_runtime:: SaturatedConversion ;
12
13
13
14
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner --exact --nocapture
14
15
#[ test]
@@ -1148,3 +1149,188 @@ fn test_swap_complex_parent_child_structure() {
1148
1149
) ;
1149
1150
} ) ;
1150
1151
}
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