Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pallets/subtensor/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ sp_api::decl_runtime_apis! {
pub trait DelegateInfoRuntimeApi {
fn get_delegates() -> Vec<DelegateInfo<AccountId32>>;
fn get_delegate( delegate_account: AccountId32 ) -> Option<DelegateInfo<AccountId32>>;
fn get_delegated( delegatee_account: AccountId32 ) -> Vec<(DelegateInfo<AccountId32>, Compact<u64>)>;
fn get_delegated( delegatee_account: AccountId32 ) -> Vec<(DelegateInfo<AccountId32>, (Compact<u16>, Compact<u64>))>;
}

pub trait NeuronInfoRuntimeApi {
Expand Down
81 changes: 52 additions & 29 deletions pallets/subtensor/src/rpc_info/delegate_info.rs
Original file line number Diff line number Diff line change
@@ -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<AccountId: TypeInfo + Encode + Decode> {
delegate_ss58: AccountId,
take: Compact<u16>,
nominators: Vec<(AccountId, Compact<u64>)>, // map of nominator_ss58 to stake amount
nominators: Vec<(AccountId, Vec<(Compact<u16>, Compact<u64>)>)>, // map of nominator_ss58 to netuid and stake amount
owner_ss58: AccountId,
registrations: Vec<Compact<u16>>, // Vec of netuid this delegate is registered on
validator_permits: Vec<Compact<u16>>, // Vec of netuid this delegate has validator permit on
Expand Down Expand Up @@ -49,19 +49,38 @@ impl<T: Config> Pallet<T> {
Self::return_per_1000_tao(take, total_stake, emissions_per_day)
}

fn get_delegate_by_existing_account(delegate: AccountIdOf<T>) -> DelegateInfo<T::AccountId> {
let mut nominators = Vec::<(T::AccountId, Compact<u64>)>::new();
fn get_delegate_by_existing_account(
delegate: AccountIdOf<T>,
skip_nominators: bool,
) -> DelegateInfo<T::AccountId> {
let mut nominators = Vec::<(T::AccountId, Vec<(Compact<u16>, Compact<u64>)>)>::new();
let mut nominator_map = BTreeMap::<T::AccountId, Vec<(Compact<u16>, Compact<u64>)>>::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::<T>::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
<Stake<T> as IterableStorageDoubleMap<T::AccountId, T::AccountId, u64>>::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());
Expand Down Expand Up @@ -112,7 +131,7 @@ impl<T: Config> Pallet<T> {
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)
}

Expand All @@ -121,7 +140,7 @@ impl<T: Config> Pallet<T> {
pub fn get_delegates() -> Vec<DelegateInfo<T::AccountId>> {
let mut delegates = Vec::<DelegateInfo<T::AccountId>>::new();
for delegate in <Delegates<T> as IterableStorageMap<T::AccountId, u16>>::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);
}

Expand All @@ -132,20 +151,24 @@ impl<T: Config> Pallet<T> {
///
pub fn get_delegated(
delegatee: T::AccountId,
) -> Vec<(DelegateInfo<T::AccountId>, Compact<u64>)> {
let mut delegates: Vec<(DelegateInfo<T::AccountId>, Compact<u64>)> = Vec::new();
) -> Vec<(DelegateInfo<T::AccountId>, (Compact<u16>, Compact<u64>))> {
let mut delegates: Vec<(DelegateInfo<T::AccountId>, (Compact<u16>, Compact<u64>))> =
Vec::new();
for delegate in <Delegates<T> as IterableStorageMap<T::AccountId, u16>>::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::<T>::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
Expand Down
16 changes: 16 additions & 0 deletions primitives/share-pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ where
.saturating_to_num::<u64>()
}

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::<u64>()
}

pub fn try_get_value(&self, key: &K) -> Result<u64, ()> {
match self.state_ops.try_get_share(key) {
Ok(_) => Ok(self.get_value(key)),
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2062,7 +2062,7 @@ impl_runtime_apis! {
SubtensorModule::get_delegate(delegate_account)
}

fn get_delegated(delegatee_account: AccountId32) -> Vec<(DelegateInfo<AccountId32>, Compact<u64>)> {
fn get_delegated(delegatee_account: AccountId32) -> Vec<(DelegateInfo<AccountId32>, (Compact<u16>, Compact<u64>))> {
SubtensorModule::get_delegated(delegatee_account)
}
}
Expand Down
Loading