code/pallets/subtensor/src/rpc_info/show_subnet.rs

show_subnet.rs

166 lines · 6,877 bytes · 19a6485969RawGitHub
use super::*;
extern crate alloc;
use crate::epoch::math::*;
use codec::Compact;
use frame_support::pallet_prelude::{Decode, Encode};
use sp_runtime::PerU16;
use substrate_fixed::types::I64F64;
use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex, TaoBalance};

#[freeze_struct("b48b8accfd0ac902")]
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)]
pub struct SubnetState<AccountId: TypeInfo + Encode + Decode> {
    netuid: Compact<NetUid>,
    hotkeys: Vec<AccountId>,
    coldkeys: Vec<AccountId>,
    active: Vec<bool>,
    validator_permit: Vec<bool>,
    pruning_score: Vec<Compact<u16>>,
    last_update: Vec<Compact<u64>>,
    emission: Vec<Compact<AlphaBalance>>,
    dividends: Vec<Compact<PerU16>>,
    incentives: Vec<Compact<PerU16>>,
    consensus: Vec<Compact<PerU16>>,
    trust: Vec<Compact<PerU16>>,
    rank: Vec<Compact<u16>>,
    block_at_registration: Vec<Compact<u64>>,
    alpha_stake: Vec<Compact<AlphaBalance>>,
    tao_stake: Vec<Compact<TaoBalance>>,
    total_stake: Vec<Compact<TaoBalance>>,
    emission_history: Vec<Vec<Compact<AlphaBalance>>>,
    // identities: Vec<ChainIdentityOf>,
    // tao_stake: Compact<u64>,
    // incentive: Compact<u16>,
    // consensus: Compact<u16>,
    // trust: Compact<u16>,
    // validator_trust: Compact<u16>,
    // dividends: Compact<u16>,
    // // has no weights or bonds
}

impl<T: Config> Pallet<T> {
    /// Retrieves the emission history for a list of hotkeys across all subnets.
    ///
    /// This function iterates over all subnets and collects the last emission value
    /// for each hotkey in the provided list. The result is a vector of vectors, where
    /// each inner vector contains the emission values for a specific subnet.
    ///
    /// # Arguments
    ///
    /// * `hotkeys`: A vector of hotkeys (account IDs) for which the emission history is to be retrieved.
    ///
    /// # Returns
    ///
    /// * `Vec<Vec<Compact<u64>>>`: A vector of vectors containing the emission history for each hotkey across all subnets.
    pub fn get_emissions_history(hotkeys: Vec<T::AccountId>) -> Vec<Vec<Compact<AlphaBalance>>> {
        let mut result: Vec<Vec<Compact<AlphaBalance>>> = vec![];
        for netuid in Self::get_all_subnet_netuids() {
            let mut hotkeys_emissions: Vec<Compact<AlphaBalance>> = vec![];
            for hotkey in hotkeys.clone() {
                let last_emission: Compact<AlphaBalance> =
                    LastHotkeyEmissionOnNetuid::<T>::get(hotkey.clone(), netuid).into();
                hotkeys_emissions.push(last_emission);
            }
            result.push(hotkeys_emissions.clone());
        }
        result
    }

    /// Retrieves the state of a specific subnet.
    ///
    /// This function gathers various metrics and data points for a given subnet, identified by its `netuid`.
    /// It collects information such as hotkeys, coldkeys, block at registration, active status, validator permits,
    /// pruning scores, last updates, emissions, dividends, incentives, consensus, trust, rank, local stake, global stake,
    /// stake weight, and emission history.
    ///
    /// # Arguments
    ///
    /// * `netuid`: The unique identifier of the subnet for which the state is to be retrieved.
    ///
    /// # Returns
    ///
    /// * `Option<SubnetState<T::AccountId>>`: An optional `SubnetState` struct containing the collected data for the subnet.
    ///   Returns `None` if the subnet does not exist.
    pub fn get_subnet_state(netuid: NetUid) -> Option<SubnetState<T::AccountId>> {
        if !Self::if_subnet_exist(netuid) {
            return None;
        }
        let n: u16 = Self::get_subnetwork_n(netuid);
        let mut hotkeys: Vec<T::AccountId> = vec![];
        let mut coldkeys: Vec<T::AccountId> = vec![];
        let mut block_at_registration: Vec<Compact<u64>> = vec![];
        // let mut identities: Vec<ChainIdentityOf> = vec![];
        for uid in 0..n {
            let hotkey = Keys::<T>::get(netuid, uid);
            let coldkey = Owner::<T>::get(hotkey.clone());
            hotkeys.push(hotkey);
            coldkeys.push(coldkey);
            block_at_registration.push(BlockAtRegistration::<T>::get(netuid, uid).into());
            // identities.push( Identities::<T>::get( coldkey.clone() ) );
        }
        let active: Vec<bool> = Active::<T>::get(netuid);
        let validator_permit: Vec<bool> = ValidatorPermit::<T>::get(netuid);
        let pruning_score: Vec<Compact<u16>> = Vec::new(); // Deprecated: no longer computed
        let last_update: Vec<Compact<u64>> = LastUpdate::<T>::get(NetUidStorageIndex::from(netuid))
            .into_iter()
            .map(Compact::from)
            .collect();
        let emission = Emission::<T>::get(netuid)
            .into_iter()
            .map(Compact::from)
            .collect();
        let dividends: Vec<Compact<PerU16>> = Dividends::<T>::get(netuid)
            .into_iter()
            .map(Compact::from)
            .collect();
        let incentives: Vec<Compact<PerU16>> =
            Incentive::<T>::get(NetUidStorageIndex::from(netuid))
                .into_iter()
                .map(Compact::from)
                .collect();
        let consensus: Vec<Compact<PerU16>> = Consensus::<T>::get(netuid)
            .into_iter()
            .map(Compact::from)
            .collect();
        let trust: Vec<Compact<PerU16>> = Vec::new(); // Deprecated: no longer computed
        let rank: Vec<Compact<u16>> = Vec::new(); // Deprecated: no longer computed
        let (total_stake_fl, alpha_stake_fl, tao_stake_fl): (
            Vec<I64F64>,
            Vec<I64F64>,
            Vec<I64F64>,
        ) = Self::get_stake_weights_for_network(netuid);
        let alpha_stake: Vec<Compact<AlphaBalance>> = alpha_stake_fl
            .iter()
            .map(|xi| Compact::from(AlphaBalance::from(fixed64_to_u64(*xi))))
            .collect();
        let tao_stake: Vec<Compact<TaoBalance>> = tao_stake_fl
            .iter()
            .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi))))
            .collect();
        let total_stake: Vec<Compact<TaoBalance>> = total_stake_fl
            .iter()
            .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi))))
            .collect();
        let emission_history = Self::get_emissions_history(hotkeys.clone());
        Some(SubnetState {
            netuid: netuid.into(),
            hotkeys,
            coldkeys,
            active,
            validator_permit,
            pruning_score,
            last_update,
            emission,
            dividends,
            incentives,
            consensus,
            trust,
            rank,
            block_at_registration,
            alpha_stake,
            tao_stake,
            total_stake,
            emission_history,
        })
    }
}