-
Notifications
You must be signed in to change notification settings - Fork 307
Bottom half median owner alpha stake #2582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
268a3ab
71241a8
82146e0
2ae4e8b
129ed47
4eb483b
11d3b05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| use super::*; | ||
| use safe_math::*; | ||
| use share_pool::{SafeFloat, SharePool, SharePoolDataOperations}; | ||
| use sp_std::{collections::btree_map::BTreeMap, ops::Neg}; | ||
| use sp_std::ops::Neg; | ||
| use substrate_fixed::types::{I64F64, I96F32, U96F32}; | ||
| use subtensor_runtime_common::{AlphaBalance, AuthorshipInfo, NetUid, TaoBalance, Token}; | ||
| use subtensor_swap_interface::{Order, SwapHandler, SwapResult}; | ||
|
|
@@ -70,73 +70,68 @@ impl<T: Config> Pallet<T> { | |
| } | ||
|
|
||
| /// Gets the Median Subnet Alpha Price | ||
| pub fn get_median_subnet_alpha_price() -> U96F32 { | ||
| pub fn get_bottom_half_median_subnet_alpha_price() -> U96F32 { | ||
| let default_price = U96F32::saturating_from_num(1_u64); | ||
| let zero_price = U96F32::saturating_from_num(0_u64); | ||
| let two = U96F32::saturating_from_num(2_u64); | ||
|
|
||
| let mut price_counts: BTreeMap<U96F32, usize> = BTreeMap::new(); | ||
| let mut total_prices: usize = 0; | ||
|
|
||
| for (netuid, added) in NetworksAdded::<T>::iter() { | ||
| if !added || netuid == NetUid::ROOT { | ||
| continue; | ||
| } | ||
|
|
||
| let price = T::SwapInterface::current_alpha_price(netuid); | ||
| if price <= zero_price { | ||
| continue; | ||
| } | ||
|
|
||
| total_prices = total_prices.saturating_add(1); | ||
|
|
||
| if let Some(count) = price_counts.get_mut(&price) { | ||
| *count = count.saturating_add(1); | ||
| } else { | ||
| price_counts.insert(price, 1usize); | ||
| } | ||
| } | ||
| let mut prices: Vec<U96F32> = NetworksAdded::<T>::iter() | ||
| .filter_map(|(netuid, added)| { | ||
| if added && netuid != NetUid::ROOT { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also match or reverse |
||
| let price = T::SwapInterface::current_alpha_price(netuid); | ||
| if price > zero_price { | ||
| Some(price) | ||
| } else { | ||
| None | ||
| } | ||
| } else { | ||
| None | ||
| } | ||
| }) | ||
| .collect(); | ||
|
|
||
| if total_prices == 0 { | ||
| if prices.is_empty() { | ||
| return default_price; | ||
| } | ||
|
|
||
| let Some(last_index) = total_prices.checked_sub(1) else { | ||
| prices.sort_unstable(); | ||
|
|
||
| let len = prices.len(); | ||
| let Some(bottom_half_len) = len.checked_add(1).and_then(|value| value.checked_div(2)) | ||
| else { | ||
| return default_price; | ||
| }; | ||
| let Some(lower_target) = last_index.checked_div(2) else { | ||
|
|
||
| let bottom_half_prices: Vec<U96F32> = prices.into_iter().take(bottom_half_len).collect(); | ||
| let bottom_len = bottom_half_prices.len(); | ||
|
|
||
| let Some(mid_index) = bottom_len.checked_div(2) else { | ||
| return default_price; | ||
| }; | ||
| let Some(upper_target) = total_prices.checked_div(2) else { | ||
|
|
||
| let Some(remainder) = bottom_len.checked_rem(2) else { | ||
| return default_price; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since your failure cases all return |
||
| }; | ||
|
|
||
| let mut cumulative: usize = 0; | ||
| let mut lower_price: Option<U96F32> = None; | ||
| let mut upper_price: Option<U96F32> = None; | ||
|
|
||
| for (price, count) in price_counts.into_iter() { | ||
| let next_cumulative = cumulative.saturating_add(count); | ||
|
|
||
| if lower_price.is_none() && lower_target < next_cumulative { | ||
| lower_price = Some(price); | ||
| } | ||
|
|
||
| if upper_price.is_none() && upper_target < next_cumulative { | ||
| upper_price = Some(price); | ||
| if remainder == 0 { | ||
| let Some(left_index) = mid_index.checked_sub(1) else { | ||
| return default_price; | ||
| }; | ||
|
|
||
| match ( | ||
| bottom_half_prices.get(left_index).copied(), | ||
| bottom_half_prices.get(mid_index).copied(), | ||
| ) { | ||
| (Some(left_price), Some(right_price)) => { | ||
| left_price.saturating_add(right_price).safe_div(two) | ||
| } | ||
| _ => default_price, | ||
| } | ||
|
|
||
| if lower_price.is_some() && upper_price.is_some() { | ||
| break; | ||
| } else { | ||
| match bottom_half_prices.get(mid_index).copied() { | ||
| Some(price) => price, | ||
| None => default_price, | ||
| } | ||
|
|
||
| cumulative = next_cumulative; | ||
| } | ||
|
|
||
| match (lower_price, upper_price) { | ||
| (Some(_), Some(upper)) if lower_target == upper_target => upper, | ||
| (Some(lower), Some(upper)) => lower.saturating_add(upper).safe_div(two), | ||
| _ => default_price, | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's something that could be reused, it's better to make it a constant instead of hardcoding, to simplify refactoring in case we would need to change the value.