@@ -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) ;
3439
3452
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 ( ) ;
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;
3488
+
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
@@ -3463,73 +3515,112 @@ fn test_dynamic_parent_child_relationships() {
3463
3515
) ) ;
3464
3516
3465
3517
// Run first epoch
3466
- let hardcoded_emission: u64 = 1_000_000 ; // 1 million (adjust as needed)
3518
+ let hardcoded_emission: u64 = 1_000_000 ;
3467
3519
3468
3520
// Step blocks to allow for emission distribution
3469
3521
step_block ( 11 ) ;
3470
3522
step_rate_limit ( & TransactionType :: SetChildren , netuid) ;
3471
3523
3524
+ // Get total stake after first payout
3525
+ let total_stake_1 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid)
3526
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid)
3527
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3528
+ log:: info!( "total_stake_1: {:?}" , total_stake_1) ;
3529
+
3472
3530
// Change parent-child relationships
3473
- mock_set_children ( & coldkey_parent, & parent, netuid, & [ ( u64:: MAX / 4 , child1) , ( u64:: MAX / 3 , child2) ] ) ;
3531
+ mock_set_children (
3532
+ & coldkey_parent,
3533
+ & parent,
3534
+ netuid,
3535
+ & [ ( u64:: MAX / 4 , child1) , ( u64:: MAX / 3 , child2) ] ,
3536
+ ) ;
3474
3537
3475
3538
// Step blocks again to allow for emission distribution
3476
3539
step_block ( 11 ) ;
3477
3540
3541
+ // Get total stake after second payout
3542
+ let total_stake_2 = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid)
3543
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid)
3544
+ + SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3545
+ log:: info!( "total_stake_2: {:?}" , total_stake_2) ;
3546
+
3478
3547
// 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) ;
3548
+ let stake_parent_2: u64 =
3549
+ SubtensorModule :: get_inherited_for_hotkey_on_subnet ( & parent, netuid) ;
3550
+ let stake_child1_2: u64 =
3551
+ SubtensorModule :: get_inherited_for_hotkey_on_subnet ( & child1, netuid) ;
3552
+ let stake_child2_2: u64 =
3553
+ SubtensorModule :: get_inherited_for_hotkey_on_subnet ( & child2, netuid) ;
3554
+ let total_parent_stake = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & parent, netuid) ;
3555
+ let total_child1_stake = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child1, netuid) ;
3556
+ let total_child2_stake = SubtensorModule :: get_stake_for_hotkey_on_subnet ( & child2, netuid) ;
3482
3557
3483
3558
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) ;
3559
+ log:: info!( "Parent stake: {}" , stake_parent_2) ;
3560
+ log:: info!( "Child1 stake: {}" , stake_child1_2) ;
3561
+ log:: info!( "Child2 stake: {}" , stake_child2_2) ;
3562
+
3563
+ // Payout 1
3564
+ let payout_1 = total_stake_1 - total_stake_0;
3565
+ log:: info!( "payout_1: {:?}" , payout_1) ;
3566
+
3567
+ // Payout 2
3568
+ let payout_2 = total_stake_2 - total_stake_1;
3569
+ log:: info!( "payout_2: {:?}" , payout_2) ;
3570
+
3571
+ let total_emission: I96F32 = I96F32 :: from_num ( payout_1 + payout_2) ;
3487
3572
3488
- const TOLERANCE : u64 = 5 ; // Allow for a small discrepancy due to potential rounding
3573
+ #[ allow( non_snake_case) ]
3574
+ let TOLERANCE : I96F32 = I96F32 :: from_num ( 0.001 ) ; // Allow for a small discrepancy due to potential rounding
3489
3575
3490
3576
// Precise assertions with tolerance
3577
+ log:: info!( "total_emission: {:?}" , total_emission) ;
3578
+ let expected_parent_stake = ( ( I96F32 :: from_num ( stake_parent_0)
3579
+ + total_emission * rel_stake_parent_0)
3580
+ * I96F32 :: from_num ( 5 ) )
3581
+ . saturating_div ( I96F32 :: from_num ( 12 ) ) ;
3491
3582
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
3583
+ ( I96F32 :: from_num( stake_parent_2) - expected_parent_stake) . abs( )
3584
+ / expected_parent_stake
3585
+ <= TOLERANCE ,
3586
+ "Parent stake should be close to {:?}, but was {}" ,
3587
+ expected_parent_stake,
3588
+ stake_parent_2
3495
3589
) ;
3496
3590
// Parent stake calculation:
3497
3591
// 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)
3592
+ // First epoch: 1/2 parent_stake
3593
+ // Second epoch: 5/12 parent_stake
3500
3594
3595
+ let expected_child1_stake = total_emission * rel_stake_child1_0
3596
+ + I96F32 :: from_num ( stake_child1_0 + ( total_parent_stake) * 1 / 4 ) ;
3501
3597
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
3598
+ ( I96F32 :: from_num( stake_child1_2) - expected_child1_stake) . abs( )
3599
+ / expected_child1_stake
3600
+ <= TOLERANCE ,
3601
+ "Child1 stake should be close to {:?}, but was {}" ,
3602
+ expected_child1_stake,
3603
+ stake_child1_2
3505
3604
) ;
3506
3605
// Child1 stake calculation:
3507
3606
// 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)
3607
+ // First epoch: 1/2 parent_stake + child1_stake
3608
+ // Second epoch: 1/4 parent_stake + child1_stake
3510
3609
3610
+ let expected_child2_stake = total_emission * rel_stake_child2_0
3611
+ + I96F32 :: from_num ( stake_child2_0 + ( total_parent_stake) * 1 / 3 ) ;
3511
3612
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
3613
+ ( I96F32 :: from_num( stake_child2_2) - expected_child2_stake) . abs( )
3614
+ / expected_child2_stake
3615
+ <= TOLERANCE ,
3616
+ "Child2 stake should be close to {:?}, but was {}" ,
3617
+ expected_child2_stake,
3618
+ stake_child2_2
3515
3619
) ;
3516
3620
// Child2 stake calculation:
3517
3621
// 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
3622
+ // First epoch: child2_stake
3623
+ // Second epoch: 1/3 parent_stake + child2_stake
3533
3624
3534
3625
// Additional checks for parent-child relationships
3535
3626
let parent_children: Vec < ( u64 , U256 ) > = SubtensorModule :: get_children ( & parent, netuid) ;
@@ -3562,21 +3653,9 @@ fn test_dynamic_parent_child_relationships() {
3562
3653
3563
3654
// Check that child2 has received more stake than child1
3564
3655
assert ! (
3565
- child2_stake > child1_stake ,
3656
+ stake_child2_2 > stake_child1_2 ,
3566
3657
"Child2 should have received more emission than Child1 due to higher proportion"
3567
3658
) ;
3568
3659
// 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
3660
} ) ;
3582
3661
}
0 commit comments