Skip to content

Commit 09e205b

Browse files
authored
Fix/per 1k estimate always zero (#1152)
* add fix for return per 1k * extract helper and add test
1 parent 2bb5e20 commit 09e205b

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

pallets/subtensor/src/rpc_info/delegate_info.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,34 @@ pub struct DelegateInfo<T: Config> {
2121
}
2222

2323
impl<T: Config> Pallet<T> {
24+
fn return_per_1000_tao(
25+
take: Compact<u16>,
26+
total_stake: U64F64,
27+
emissions_per_day: U64F64,
28+
) -> U64F64 {
29+
// Get the take as a percentage and subtract it from 1 for remainder.
30+
let without_take: U64F64 = U64F64::from_num(1)
31+
.saturating_sub(U64F64::from_num(take.0).saturating_div(u16::MAX.into()));
32+
33+
if total_stake > U64F64::from_num(0) {
34+
emissions_per_day
35+
.saturating_mul(without_take)
36+
// Divide by 1000 TAO for return per 1k
37+
.saturating_div(total_stake.saturating_div(U64F64::from_num(1000.0 * 1e9)))
38+
} else {
39+
U64F64::from_num(0)
40+
}
41+
}
42+
43+
#[cfg(test)]
44+
pub fn return_per_1000_tao_test(
45+
take: Compact<u16>,
46+
total_stake: U64F64,
47+
emissions_per_day: U64F64,
48+
) -> U64F64 {
49+
Self::return_per_1000_tao(take, total_stake, emissions_per_day)
50+
}
51+
2452
fn get_delegate_by_existing_account(delegate: AccountIdOf<T>) -> DelegateInfo<T> {
2553
let mut nominators = Vec::<(T::AccountId, Compact<u64>)>::new();
2654

@@ -63,14 +91,8 @@ impl<T: Config> Pallet<T> {
6391
let total_stake: U64F64 =
6492
Self::get_stake_for_hotkey_on_subnet(&delegate.clone(), Self::get_root_netuid()).into();
6593

66-
let return_per_1000: U64F64 = if total_stake > U64F64::from_num(0) {
67-
emissions_per_day
68-
.saturating_mul(u16::MAX.saturating_sub(take.0).into())
69-
.saturating_div(u16::MAX.into())
70-
.saturating_div(total_stake.saturating_div(U64F64::from_num(1000)))
71-
} else {
72-
U64F64::from_num(0)
73-
};
94+
let return_per_1000: U64F64 =
95+
Self::return_per_1000_tao(take, total_stake, emissions_per_day);
7496

7597
DelegateInfo {
7698
delegate_ss58: delegate.clone(),
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use codec::Compact;
2+
use substrate_fixed::types::U64F64;
3+
4+
use super::mock::*;
5+
6+
#[test]
7+
fn test_return_per_1000_tao() {
8+
let take = // 18% take to the Validator
9+
Compact::<u16>::from((U64F64::from_num(0.18 * u16::MAX as f64)).saturating_to_num::<u16>());
10+
11+
// 10_000 TAO total validator stake
12+
let total_stake = U64F64::from_num(10_000.0 * 1e9);
13+
// 1000 TAO emissions per day
14+
let emissions_per_day = U64F64::from_num(1000.0 * 1e9);
15+
16+
let return_per_1000 =
17+
SubtensorModule::return_per_1000_tao_test(take, total_stake, emissions_per_day);
18+
19+
// We expect 82 TAO per day with 10% of total_stake
20+
let expected_return_per_1000 = U64F64::from_num(82.0);
21+
22+
let diff_from_expected: f64 = (return_per_1000 / U64F64::from_num(1e9))
23+
.saturating_sub(expected_return_per_1000)
24+
.to_num::<f64>();
25+
26+
let eps: f64 = 0.0005e9; // Precision within 0.0005 TAO
27+
assert!(
28+
diff_from_expected.abs() <= eps,
29+
"Difference from expected: {} is greater than precision: {}",
30+
diff_from_expected,
31+
eps
32+
);
33+
}

pallets/subtensor/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod batch_tx;
22
mod children;
33
mod coinbase;
4+
mod delegate_info;
45
mod difficulty;
56
mod emission;
67
mod epoch;

0 commit comments

Comments
 (0)