@@ -3412,7 +3412,7 @@ fn test_parent_child_chain_emission() {
3412
3412
// - Runs second epoch and distributes emissions
3413
3413
// - Checks final emission distribution and stake updates
3414
3414
// - Verifies correct parent-child relationships and stake proportions
3415
- // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_dynamic_parent_child_relationships --exact --nocapture
3415
+ // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::children:: test_dynamic_parent_child_relationships --exact --show-output
3416
3416
#[ test]
3417
3417
fn test_dynamic_parent_child_relationships ( ) {
3418
3418
new_test_ext ( 1 ) . execute_with ( || {
@@ -3432,14 +3432,66 @@ fn test_dynamic_parent_child_relationships() {
3432
3432
register_ok_neuron ( netuid, child1, coldkey_child1, 0 ) ;
3433
3433
register_ok_neuron ( netuid, child2, coldkey_child2, 0 ) ;
3434
3434
3435
+ let chk_take_1 = SubtensorModule :: get_childkey_take ( & child1, netuid) ;
3436
+ let chk_take_2 = SubtensorModule :: get_childkey_take ( & child2, netuid) ;
3437
+ log:: info!( "child take 1: {:?}" , chk_take_1) ;
3438
+ log:: info!( "child take 2: {:?}" , chk_take_2) ;
3439
+
3435
3440
// Add initial stakes
3436
- SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_parent, 500_000 ) ;
3437
- SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_child1, 50_000 ) ;
3438
- SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_child2, 30_000 ) ;
3441
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_parent, 500_000 + 1_000 ) ;
3442
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_child1, 50_000 + 1_000 ) ;
3443
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_child2, 30_000 + 1_000 ) ;
3444
+
3445
+ // Swap to alpha
3446
+ let total_tao: I96F32 = I96F32 :: from_num ( 500_000 + 50_000 + 30_000 ) ;
3447
+ let total_alpha: I96F32 = I96F32 :: from_num ( SubtensorModule :: swap_tao_for_alpha (
3448
+ netuid,
3449
+ total_tao. saturating_to_num :: < u64 > ( ) ,
3450
+ ) ) ;
3451
+ log:: info!( "total_alpha: {:?}" , total_alpha) ;
3452
+
3453
+ // Set the stakes directly
3454
+ // This avoids needing to swap tao to alpha, impacting the initial stake distribution.
3455
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
3456
+ & parent,
3457
+ & coldkey_parent,
3458
+ netuid,
3459
+ ( total_alpha * I96F32 :: from_num ( 500_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
3460
+ ) ;
3461
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
3462
+ & child1,
3463
+ & coldkey_child1,
3464
+ netuid,
3465
+ ( total_alpha * I96F32 :: from_num ( 50_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
3466
+ ) ;
3467
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
3468
+ & child2,
3469
+ & coldkey_child2,
3470
+ netuid,
3471
+ ( total_alpha * I96F32 :: from_num ( 30_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
3472
+ ) ;
3473
+
3474
+ // Get old stakes
3475
+ let stake_parent_0: u64 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid) ;
3476
+ let stake_child1_0: u64 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid) ;
3477
+ let stake_child2_0: u64 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3478
+ log:: info!( "stake_parent_0: {:?}" , stake_parent_0) ;
3479
+ log:: info!( "stake_child1_0: {:?}" , stake_child1_0) ;
3480
+ log:: info!( "stake_child2_0: {:?}" , stake_child2_0) ;
3481
+
3482
+ let total_stake_0: u64 = stake_parent_0 + stake_child1_0 + stake_child2_0;
3483
+
3484
+ // Assert initial stake is correct
3485
+ let rel_stake_parent_0 = I96F32 :: from_num ( stake_parent_0) / total_tao;
3486
+ let rel_stake_child1_0 = I96F32 :: from_num ( stake_child1_0) / total_tao;
3487
+ let rel_stake_child2_0 = I96F32 :: from_num ( stake_child2_0) / total_tao;
3439
3488
3440
- SubtensorModule :: add_stake ( RuntimeOrigin :: signed ( coldkey_parent) , parent, netuid, 500_000 ) . unwrap ( ) ;
3441
- SubtensorModule :: add_stake ( RuntimeOrigin :: signed ( coldkey_child1) , child1, netuid, 50_000 ) . unwrap ( ) ;
3442
- SubtensorModule :: add_stake ( RuntimeOrigin :: signed ( coldkey_child2) , child2, netuid, 30_000 ) . unwrap ( ) ;
3489
+ log:: info!( "rel_stake_parent_0: {:?}" , rel_stake_parent_0) ;
3490
+ log:: info!( "rel_stake_child1_0: {:?}" , rel_stake_child1_0) ;
3491
+ log:: info!( "rel_stake_child2_0: {:?}" , rel_stake_child2_0) ;
3492
+ assert_eq ! ( rel_stake_parent_0, I96F32 :: from_num( 500_000 ) / total_tao) ;
3493
+ assert_eq ! ( rel_stake_child1_0, I96F32 :: from_num( 50_000 ) / total_tao) ;
3494
+ assert_eq ! ( rel_stake_child2_0, I96F32 :: from_num( 30_000 ) / total_tao) ;
3443
3495
3444
3496
mock_set_children ( & coldkey_parent, & parent, netuid, & [ ( u64:: MAX / 2 , child1) ] ) ;
3445
3497
@@ -3462,74 +3514,110 @@ fn test_dynamic_parent_child_relationships() {
3462
3514
version_key
3463
3515
) ) ;
3464
3516
3465
- // Run first epoch
3466
- let hardcoded_emission: u64 = 1_000_000 ; // 1 million (adjust as needed)
3467
-
3468
3517
// Step blocks to allow for emission distribution
3469
3518
step_block ( 11 ) ;
3470
3519
step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
3471
3520
3521
+ // Get total stake after first payout
3522
+ let total_stake_1 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid)
3523
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid)
3524
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3525
+ log:: info!( "total_stake_1: {:?}" , total_stake_1) ;
3526
+
3472
3527
// Change parent-child relationships
3473
- mock_set_children ( & coldkey_parent, & parent, netuid, & [ ( u64:: MAX / 4 , child1) , ( u64:: MAX / 3 , child2) ] ) ;
3528
+ mock_set_children (
3529
+ & coldkey_parent,
3530
+ & parent,
3531
+ netuid,
3532
+ & [ ( u64:: MAX / 4 , child1) , ( u64:: MAX / 3 , child2) ] ,
3533
+ ) ;
3474
3534
3475
3535
// Step blocks again to allow for emission distribution
3476
3536
step_block ( 11 ) ;
3477
3537
3538
+ // Get total stake after second payout
3539
+ let total_stake_2 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid)
3540
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid)
3541
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3542
+ log:: info!( "total_stake_2: {:?}" , total_stake_2) ;
3543
+
3478
3544
// Check final emission distribution
3479
- let parent_stake: u64 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid) ;
3480
- let child1_stake: u64 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid) ;
3481
- let child2_stake: u64 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3545
+ let stake_parent_2: u64 =
3546
+ SubtensorModule :: get_inherited_for_hotkey_on_subnet ( & parent, netuid) ;
3547
+ let stake_child1_2: u64 =
3548
+ SubtensorModule :: get_inherited_for_hotkey_on_subnet ( & child1, netuid) ;
3549
+ let stake_child2_2: u64 =
3550
+ SubtensorModule :: get_inherited_for_hotkey_on_subnet ( & child2, netuid) ;
3551
+ let total_parent_stake = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid) ;
3552
+ let _total_child1_stake = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid) ;
3553
+ let _total_child2_stake = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3482
3554
3483
3555
log:: info!( "Final stakes:" ) ;
3484
- log:: info!( "Parent stake: {}" , parent_stake) ;
3485
- log:: info!( "Child1 stake: {}" , child1_stake) ;
3486
- log:: info!( "Child2 stake: {}" , child2_stake) ;
3556
+ log:: info!( "Parent stake: {}" , stake_parent_2) ;
3557
+ log:: info!( "Child1 stake: {}" , stake_child1_2) ;
3558
+ log:: info!( "Child2 stake: {}" , stake_child2_2) ;
3559
+
3560
+ // Payout 1
3561
+ let payout_1 = total_stake_1 - total_stake_0;
3562
+ log:: info!( "payout_1: {:?}" , payout_1) ;
3563
+
3564
+ // Payout 2
3565
+ let payout_2 = total_stake_2 - total_stake_1;
3566
+ log:: info!( "payout_2: {:?}" , payout_2) ;
3567
+
3568
+ let total_emission: I96F32 = I96F32 :: from_num ( payout_1 + payout_2) ;
3487
3569
3488
- const TOLERANCE : u64 = 5 ; // Allow for a small discrepancy due to potential rounding
3570
+ #[ allow( non_snake_case) ]
3571
+ let TOLERANCE : I96F32 = I96F32 :: from_num ( 0.001 ) ; // Allow for a small discrepancy due to potential rounding
3489
3572
3490
3573
// Precise assertions with tolerance
3574
+ log:: info!( "total_emission: {:?}" , total_emission) ;
3575
+ let expected_parent_stake = ( ( I96F32 :: from_num ( stake_parent_0)
3576
+ + total_emission * rel_stake_parent_0)
3577
+ * I96F32 :: from_num ( 5 ) )
3578
+ . saturating_div ( I96F32 :: from_num ( 12 ) ) ;
3491
3579
assert ! (
3492
- ( parent_stake as i128 - 926725i128 ) . abs( ) <= TOLERANCE as i128 ,
3493
- "Parent stake should be close to 926,725, but was {}" ,
3494
- parent_stake
3580
+ ( I96F32 :: from_num( stake_parent_2) - expected_parent_stake) . abs( )
3581
+ / expected_parent_stake
3582
+ <= TOLERANCE ,
3583
+ "Parent stake should be close to {:?}, but was {}" ,
3584
+ expected_parent_stake,
3585
+ stake_parent_2
3495
3586
) ;
3496
3587
// Parent stake calculation:
3497
3588
// Initial stake: 500,000
3498
- // First epoch: ~862,500 (500,000 + 725,000 * 1/2)
3499
- // Second epoch: ~926,725 (862,500 + 725,000 * 5/12)
3589
+ // First epoch: 1/2 parent_stake
3590
+ // Second epoch: 5/12 parent_stake
3500
3591
3592
+ let expected_child1_stake = total_emission * rel_stake_child1_0
3593
+ + I96F32 :: from_num ( stake_child1_0 + ( total_parent_stake) / 4 ) ;
3501
3594
assert ! (
3502
- ( child1_stake as i64 - 778446 ) . abs( ) <= TOLERANCE as i64 ,
3503
- "Child1 stake should be close to 778,446, but was {}" ,
3504
- child1_stake
3595
+ ( I96F32 :: from_num( stake_child1_2) - expected_child1_stake) . abs( )
3596
+ / expected_child1_stake
3597
+ <= TOLERANCE ,
3598
+ "Child1 stake should be close to {:?}, but was {}" ,
3599
+ expected_child1_stake,
3600
+ stake_child1_2
3505
3601
) ;
3506
3602
// Child1 stake calculation:
3507
3603
// Initial stake: 50,000
3508
- // First epoch: ~412,500 (50,000 + 725,000 * 1/2)
3509
- // Second epoch: ~778,446 (412,500 + 725,000 * 1/2 * 1/4 + 137,500)
3604
+ // First epoch: 1/2 parent_stake + child1_stake
3605
+ // Second epoch: 1/4 parent_stake + child1_stake
3510
3606
3607
+ let expected_child2_stake = total_emission * rel_stake_child2_0
3608
+ + I96F32 :: from_num ( stake_child2_0 + ( total_parent_stake) / 3 ) ;
3511
3609
assert ! (
3512
- ( child2_stake as i64 - 874826 ) . abs( ) <= TOLERANCE as i64 ,
3513
- "Child2 stake should be close to 874,826, but was {}" ,
3514
- child2_stake
3610
+ ( I96F32 :: from_num( stake_child2_2) - expected_child2_stake) . abs( )
3611
+ / expected_child2_stake
3612
+ <= TOLERANCE ,
3613
+ "Child2 stake should be close to {:?}, but was {}" ,
3614
+ expected_child2_stake,
3615
+ stake_child2_2
3515
3616
) ;
3516
3617
// Child2 stake calculation:
3517
3618
// Initial stake: 30,000
3518
- // First epoch: ~167,500 (30,000 + 137,500)
3519
- // Second epoch: ~874,826 (167,500 + 725,000 * 1/2 * 1/3 + 137,500)
3520
-
3521
- // Check that the total stake has increased by approximately twice the hardcoded emission amount
3522
- let total_stake: u64 = parent_stake + child1_stake + child2_stake;
3523
- let initial_total_stake: u64 = 500_000 + 50_000 + 30_000 ;
3524
- let total_emission: u64 = 2 * hardcoded_emission;
3525
- assert ! (
3526
- ( total_stake as i64 - ( initial_total_stake + total_emission) as i64 ) . abs( ) <= TOLERANCE as i64 ,
3527
- "Total stake should have increased by approximately twice the hardcoded emission amount"
3528
- ) ;
3529
- // Total stake calculation:
3530
- // Initial total stake: 500,000 + 50,000 + 30,000 = 580,000
3531
- // Total emission: 2 * 1,000,000 = 2,000,000
3532
- // Expected total stake: 580,000 + 2,000,000 = 2,580,000
3619
+ // First epoch: child2_stake
3620
+ // Second epoch: 1/3 parent_stake + child2_stake
3533
3621
3534
3622
// Additional checks for parent-child relationships
3535
3623
let parent_children: Vec < ( u64 , U256 ) > = SubtensorModule :: get_children ( & parent, netuid) ;
@@ -3562,21 +3650,9 @@ fn test_dynamic_parent_child_relationships() {
3562
3650
3563
3651
// Check that child2 has received more stake than child1
3564
3652
assert ! (
3565
- child2_stake > child1_stake ,
3653
+ stake_child2_2 > stake_child1_2 ,
3566
3654
"Child2 should have received more emission than Child1 due to higher proportion"
3567
3655
) ;
3568
3656
// Child2 stake (874,826) > Child1 stake (778,446)
3569
-
3570
- // Check the approximate difference between child2 and child1 stakes
3571
- let stake_difference: u64 = child2_stake - child1_stake;
3572
- assert ! (
3573
- ( stake_difference as i64 - 96_380 ) . abs( ) <= TOLERANCE as i64 ,
3574
- "The difference between Child2 and Child1 stakes should be close to 96,380, but was {}" ,
3575
- stake_difference
3576
- ) ;
3577
- // Stake difference calculation:
3578
- // Child2 stake: 874,826
3579
- // Child1 stake: 778,446
3580
- // Difference: 874,826 - 778,446 = 96,380
3581
3657
} ) ;
3582
3658
}
0 commit comments