diff --git a/pallets/subtensor/runtime-api/src/lib.rs b/pallets/subtensor/runtime-api/src/lib.rs index 9f6d960407..c6665bcd97 100644 --- a/pallets/subtensor/runtime-api/src/lib.rs +++ b/pallets/subtensor/runtime-api/src/lib.rs @@ -19,7 +19,7 @@ sp_api::decl_runtime_apis! { pub trait DelegateInfoRuntimeApi { fn get_delegates() -> Vec>; fn get_delegate( delegate_account: AccountId32 ) -> Option>; - fn get_delegated( delegatee_account: AccountId32 ) -> Vec<(DelegateInfo, Compact)>; + fn get_delegated( delegatee_account: AccountId32 ) -> Vec<(DelegateInfo, (Compact, Compact))>; } pub trait NeuronInfoRuntimeApi { diff --git a/pallets/subtensor/src/rpc_info/delegate_info.rs b/pallets/subtensor/src/rpc_info/delegate_info.rs index acfe28b43d..8c437efc70 100644 --- a/pallets/subtensor/src/rpc_info/delegate_info.rs +++ b/pallets/subtensor/src/rpc_info/delegate_info.rs @@ -1,18 +1,18 @@ use super::*; use frame_support::pallet_prelude::{Decode, Encode}; -use frame_support::storage::IterableStorageMap; -use frame_support::IterableStorageDoubleMap; +use frame_support::IterableStorageMap; use safe_math::*; use substrate_fixed::types::U64F64; extern crate alloc; +use alloc::collections::BTreeMap; use codec::Compact; -#[freeze_struct("66105c2cfec0608d")] +#[freeze_struct("f729f2481d94a1de")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct DelegateInfo { delegate_ss58: AccountId, take: Compact, - nominators: Vec<(AccountId, Compact)>, // map of nominator_ss58 to stake amount + nominators: Vec<(AccountId, Vec<(Compact, Compact)>)>, // map of nominator_ss58 to netuid and stake amount owner_ss58: AccountId, registrations: Vec>, // Vec of netuid this delegate is registered on validator_permits: Vec>, // Vec of netuid this delegate has validator permit on @@ -49,19 +49,38 @@ impl Pallet { Self::return_per_1000_tao(take, total_stake, emissions_per_day) } - fn get_delegate_by_existing_account(delegate: AccountIdOf) -> DelegateInfo { - let mut nominators = Vec::<(T::AccountId, Compact)>::new(); + fn get_delegate_by_existing_account( + delegate: AccountIdOf, + skip_nominators: bool, + ) -> DelegateInfo { + let mut nominators = Vec::<(T::AccountId, Vec<(Compact, Compact)>)>::new(); + let mut nominator_map = BTreeMap::, Compact)>>::new(); + + if !skip_nominators { + let mut alpha_share_pools = vec![]; + for netuid in Self::get_all_subnet_netuids() { + let alpha_share_pool = Self::get_alpha_share_pool(delegate.clone(), netuid); + alpha_share_pools.push(alpha_share_pool); + } + + for ((nominator, netuid), alpha_stake) in Alpha::::iter_prefix((delegate.clone(),)) { + if alpha_stake == 0 { + continue; + } + + if let Some(alpha_share_pool) = alpha_share_pools.get(netuid as usize) { + let coldkey_stake = alpha_share_pool.get_value_from_shares(alpha_stake); - for (nominator, stake) in - as IterableStorageDoubleMap>::iter_prefix( - delegate.clone(), - ) - { - if stake == 0 { - continue; + nominator_map + .entry(nominator.clone()) + .or_insert(Vec::new()) + .push((netuid.into(), coldkey_stake.into())); + } + } + + for (nominator, stakes) in nominator_map { + nominators.push((nominator, stakes)); } - // Only add nominators with stake - nominators.push((nominator.clone(), stake.into())); } let registrations = Self::get_registered_networks_for_hotkey(&delegate.clone()); @@ -112,7 +131,7 @@ impl Pallet { return None; } - let delegate_info = Self::get_delegate_by_existing_account(delegate.clone()); + let delegate_info = Self::get_delegate_by_existing_account(delegate.clone(), false); Some(delegate_info) } @@ -121,7 +140,7 @@ impl Pallet { pub fn get_delegates() -> Vec> { let mut delegates = Vec::>::new(); for delegate in as IterableStorageMap>::iter_keys() { - let delegate_info = Self::get_delegate_by_existing_account(delegate.clone()); + let delegate_info = Self::get_delegate_by_existing_account(delegate.clone(), false); delegates.push(delegate_info); } @@ -132,20 +151,24 @@ impl Pallet { /// pub fn get_delegated( delegatee: T::AccountId, - ) -> Vec<(DelegateInfo, Compact)> { - let mut delegates: Vec<(DelegateInfo, Compact)> = Vec::new(); + ) -> Vec<(DelegateInfo, (Compact, Compact))> { + let mut delegates: Vec<(DelegateInfo, (Compact, Compact))> = + Vec::new(); for delegate in as IterableStorageMap>::iter_keys() { // Staked to this delegate, so add to list - let delegate_info = Self::get_delegate_by_existing_account(delegate.clone()); - delegates.push(( - delegate_info, - Self::get_stake_for_hotkey_and_coldkey_on_subnet( - &delegatee, - &delegate, - Self::get_root_netuid(), - ) - .into(), - )); + for (netuid, _) in Alpha::::iter_prefix((delegate.clone(), delegatee.clone())) { + let delegate_info = Self::get_delegate_by_existing_account(delegate.clone(), true); + delegates.push(( + delegate_info, + ( + netuid.into(), + Self::get_stake_for_hotkey_and_coldkey_on_subnet( + &delegate, &delegatee, netuid, + ) + .into(), + ), + )); + } } delegates diff --git a/primitives/share-pool/src/lib.rs b/primitives/share-pool/src/lib.rs index a49187ae07..d43f36259c 100644 --- a/primitives/share-pool/src/lib.rs +++ b/primitives/share-pool/src/lib.rs @@ -63,6 +63,22 @@ where .saturating_to_num::() } + pub fn get_value_from_shares(&self, current_share: U64F64) -> u64 { + let shared_value: U64F64 = self.state_ops.get_shared_value(); + let denominator: U64F64 = self.state_ops.get_denominator(); + + let maybe_value_per_share = shared_value.checked_div(denominator); + (if let Some(value_per_share) = maybe_value_per_share { + value_per_share.saturating_mul(current_share) + } else { + shared_value + .saturating_mul(current_share) + .checked_div(denominator) + .unwrap_or(U64F64::saturating_from_num(0)) + }) + .saturating_to_num::() + } + pub fn try_get_value(&self, key: &K) -> Result { match self.state_ops.try_get_share(key) { Ok(_) => Ok(self.get_value(key)), diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 0320e89983..c796296da7 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -2062,7 +2062,7 @@ impl_runtime_apis! { SubtensorModule::get_delegate(delegate_account) } - fn get_delegated(delegatee_account: AccountId32) -> Vec<(DelegateInfo, Compact)> { + fn get_delegated(delegatee_account: AccountId32) -> Vec<(DelegateInfo, (Compact, Compact))> { SubtensorModule::get_delegated(delegatee_account) } }