@@ -172,6 +172,8 @@ fn test_do_set_child_singular_old_children_cleanup() {
172
172
vec![ ( proportion, old_child) ]
173
173
) ) ;
174
174
175
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
176
+
175
177
// Set new child
176
178
assert_ok ! ( SubtensorModule :: do_set_children(
177
179
RuntimeOrigin :: signed( coldkey) ,
@@ -260,6 +262,8 @@ fn test_do_set_child_singular_proportion_edge_cases() {
260
262
let children = SubtensorModule :: get_children ( & hotkey, netuid) ;
261
263
assert_eq ! ( children, vec![ ( min_proportion, child) ] ) ;
262
264
265
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
266
+
263
267
// Set child with maximum proportion
264
268
let max_proportion: u64 = u64:: MAX ;
265
269
assert_ok ! ( SubtensorModule :: do_set_children(
@@ -306,6 +310,8 @@ fn test_do_set_child_singular_multiple_children() {
306
310
vec![ ( proportion1, child1) ]
307
311
) ) ;
308
312
313
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
314
+
309
315
// Set second child
310
316
assert_ok ! ( SubtensorModule :: do_set_children(
311
317
RuntimeOrigin :: signed( coldkey) ,
@@ -351,6 +357,7 @@ fn test_add_singular_child() {
351
357
Err ( Error :: <Test >:: SubNetworkDoesNotExist . into( ) )
352
358
) ;
353
359
add_network ( netuid, 0 , 0 ) ;
360
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
354
361
assert_eq ! (
355
362
SubtensorModule :: do_set_children(
356
363
RuntimeOrigin :: signed( coldkey) ,
@@ -361,6 +368,7 @@ fn test_add_singular_child() {
361
368
Err ( Error :: <Test >:: NonAssociatedColdKey . into( ) )
362
369
) ;
363
370
SubtensorModule :: create_account_if_non_existent ( & coldkey, & hotkey) ;
371
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
364
372
assert_eq ! (
365
373
SubtensorModule :: do_set_children(
366
374
RuntimeOrigin :: signed( coldkey) ,
@@ -371,6 +379,7 @@ fn test_add_singular_child() {
371
379
Err ( Error :: <Test >:: InvalidChild . into( ) )
372
380
) ;
373
381
let child = U256 :: from ( 3 ) ;
382
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
374
383
assert_ok ! ( SubtensorModule :: do_set_children(
375
384
RuntimeOrigin :: signed( coldkey) ,
376
385
hotkey,
@@ -467,6 +476,8 @@ fn test_do_revoke_child_singular_success() {
467
476
let children = SubtensorModule :: get_children ( & hotkey, netuid) ;
468
477
assert_eq ! ( children, vec![ ( proportion, child) ] ) ;
469
478
479
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
480
+
470
481
// Revoke child
471
482
assert_ok ! ( SubtensorModule :: do_set_children(
472
483
RuntimeOrigin :: signed( coldkey) ,
@@ -764,6 +775,8 @@ fn test_do_set_children_multiple_old_children_cleanup() {
764
775
vec![ ( proportion, old_child) ]
765
776
) ) ;
766
777
778
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
779
+
767
780
// Set new children
768
781
assert_ok ! ( SubtensorModule :: do_set_children(
769
782
RuntimeOrigin :: signed( coldkey) ,
@@ -854,6 +867,8 @@ fn test_do_set_children_multiple_overwrite_existing() {
854
867
vec![ ( proportion, child1) , ( proportion, child2) ]
855
868
) ) ;
856
869
870
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
871
+
857
872
// Overwrite with new children
858
873
assert_ok ! ( SubtensorModule :: do_set_children(
859
874
RuntimeOrigin :: signed( coldkey) ,
@@ -999,7 +1014,7 @@ fn test_childkey_take_rate_limiting() {
999
1014
& hotkey,
1000
1015
netuid,
1001
1016
) ;
1002
- let limit = SubtensorModule :: get_rate_limit ( & TransactionType :: SetChildkeyTake ) ;
1017
+ let limit = SubtensorModule :: get_rate_limit ( & TransactionType :: SetChildkeyTake , 0 ) ;
1003
1018
log:: info!(
1004
1019
"Rate limit info: current_block: {}, last_block: {}, limit: {}, passes: {}, diff: {}" ,
1005
1020
current_block,
@@ -1199,6 +1214,8 @@ fn test_do_revoke_children_multiple_success() {
1199
1214
vec![ ( proportion1, child1) , ( proportion2, child2) ]
1200
1215
) ) ;
1201
1216
1217
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
1218
+
1202
1219
// Revoke multiple children
1203
1220
assert_ok ! ( SubtensorModule :: do_set_children(
1204
1221
RuntimeOrigin :: signed( coldkey) ,
@@ -1313,6 +1330,8 @@ fn test_do_revoke_children_multiple_partial_revocation() {
1313
1330
]
1314
1331
) ) ;
1315
1332
1333
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
1334
+
1316
1335
// Revoke only child3
1317
1336
assert_ok ! ( SubtensorModule :: do_set_children(
1318
1337
RuntimeOrigin :: signed( coldkey) ,
@@ -1364,6 +1383,8 @@ fn test_do_revoke_children_multiple_non_existent_children() {
1364
1383
vec![ ( proportion, child1) ]
1365
1384
) ) ;
1366
1385
1386
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
1387
+
1367
1388
// Attempt to revoke existing and non-existent children
1368
1389
assert_ok ! ( SubtensorModule :: do_set_children(
1369
1390
RuntimeOrigin :: signed( coldkey) ,
@@ -1450,6 +1471,8 @@ fn test_do_revoke_children_multiple_complex_scenario() {
1450
1471
]
1451
1472
) ) ;
1452
1473
1474
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
1475
+
1453
1476
// Revoke child2
1454
1477
assert_ok ! ( SubtensorModule :: do_set_children(
1455
1478
RuntimeOrigin :: signed( coldkey) ,
@@ -1466,6 +1489,8 @@ fn test_do_revoke_children_multiple_complex_scenario() {
1466
1489
let parents2 = SubtensorModule :: get_parents ( & child2, netuid) ;
1467
1490
assert ! ( parents2. is_empty( ) ) ;
1468
1491
1492
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
1493
+
1469
1494
// Revoke remaining children
1470
1495
assert_ok ! ( SubtensorModule :: do_set_children(
1471
1496
RuntimeOrigin :: signed( coldkey) ,
@@ -2374,6 +2399,7 @@ fn test_dynamic_parent_child_relationships() {
2374
2399
step_block ( 11 ) ;
2375
2400
2376
2401
// Change parent-child relationships
2402
+ step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
2377
2403
assert_ok ! ( SubtensorModule :: do_set_children(
2378
2404
RuntimeOrigin :: signed( coldkey_parent) ,
2379
2405
parent,
@@ -3702,3 +3728,78 @@ fn test_childkey_take_drain_validator_take() {
3702
3728
) ) ;
3703
3729
} ) ;
3704
3730
}
3731
+
3732
+ // 60: Test set_children rate limiting - Fail then succeed
3733
+ // This test ensures that an immediate second `set_children` transaction fails due to rate limiting:
3734
+ // - Sets up a network and registers a hotkey
3735
+ // - Performs a `set_children` transaction
3736
+ // - Attempts a second `set_children` transaction immediately
3737
+ // - Verifies that the second transaction fails with `TxRateLimitExceeded`
3738
+ // Then the rate limit period passes and the second transaction succeeds
3739
+ // - Steps blocks for the rate limit period
3740
+ // - Attempts the second transaction again and verifies it succeeds
3741
+ // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_set_children_rate_limit_fail_then_succeed --exact --nocapture
3742
+ #[ test]
3743
+ fn test_set_children_rate_limit_fail_then_succeed ( ) {
3744
+ new_test_ext ( 1 ) . execute_with ( || {
3745
+ let coldkey = U256 :: from ( 1 ) ;
3746
+ let hotkey = U256 :: from ( 2 ) ;
3747
+ let child = U256 :: from ( 3 ) ;
3748
+ let child2 = U256 :: from ( 4 ) ;
3749
+ let netuid: u16 = 1 ;
3750
+ let tempo = 13 ;
3751
+
3752
+ // Add network and register hotkey
3753
+ add_network ( netuid, tempo, 0 ) ;
3754
+ register_ok_neuron ( netuid, hotkey, coldkey, 0 ) ;
3755
+
3756
+ // First set_children transaction
3757
+ assert_ok ! ( SubtensorModule :: do_set_children(
3758
+ RuntimeOrigin :: signed( coldkey) ,
3759
+ hotkey,
3760
+ netuid,
3761
+ vec![ ( 100 , child) ]
3762
+ ) ) ;
3763
+
3764
+ // Immediate second transaction should fail due to rate limit
3765
+ assert_noop ! (
3766
+ SubtensorModule :: do_set_children(
3767
+ RuntimeOrigin :: signed( coldkey) ,
3768
+ hotkey,
3769
+ netuid,
3770
+ vec![ ( 100 , child2) ]
3771
+ ) ,
3772
+ Error :: <Test >:: TxRateLimitExceeded
3773
+ ) ;
3774
+
3775
+ // Verify first children assignment remains
3776
+ let children = SubtensorModule :: get_children ( & hotkey, netuid) ;
3777
+ assert_eq ! ( children, vec![ ( 100 , child) ] ) ;
3778
+
3779
+ // Try again after rate limit period has passed
3780
+ // Check rate limit
3781
+ let limit = SubtensorModule :: get_rate_limit ( & TransactionType :: SetChildren , netuid) ;
3782
+
3783
+ // Step that many blocks
3784
+ step_block ( limit as u16 ) ;
3785
+
3786
+ // Verify rate limit passes
3787
+ assert ! ( SubtensorModule :: passes_rate_limit_on_subnet(
3788
+ & TransactionType :: SetChildren ,
3789
+ & hotkey,
3790
+ netuid
3791
+ ) ) ;
3792
+
3793
+ // Try again
3794
+ assert_ok ! ( SubtensorModule :: do_set_children(
3795
+ RuntimeOrigin :: signed( coldkey) ,
3796
+ hotkey,
3797
+ netuid,
3798
+ vec![ ( 100 , child2) ]
3799
+ ) ) ;
3800
+
3801
+ // Verify children assignment has changed
3802
+ let children = SubtensorModule :: get_children ( & hotkey, netuid) ;
3803
+ assert_eq ! ( children, vec![ ( 100 , child2) ] ) ;
3804
+ } ) ;
3805
+ }
0 commit comments