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

neuron_info.rs

234 lines · 8,543 bytes · 19a6485969RawGitHub
use super::*;
use frame_support::pallet_prelude::{Decode, Encode};
extern crate alloc;
use codec::Compact;
use sp_runtime::PerU16;
use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex};

#[freeze_struct("77daa43c02912b80")]
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)]
pub struct NeuronInfo<AccountId: TypeInfo + Encode + Decode> {
    hotkey: AccountId,
    coldkey: AccountId,
    uid: Compact<u16>,
    netuid: Compact<NetUid>,
    active: bool,
    axon_info: AxonInfo,
    prometheus_info: PrometheusInfo,
    stake: Vec<(AccountId, Compact<AlphaBalance>)>, // map of coldkey to stake on this neuron/hotkey (includes delegations)
    rank: Compact<u16>,
    emission: Compact<AlphaBalance>,
    incentive: Compact<PerU16>,
    consensus: Compact<PerU16>,
    trust: Compact<PerU16>,
    validator_trust: Compact<PerU16>,
    dividends: Compact<PerU16>,
    last_update: Compact<u64>,
    validator_permit: bool,
    weights: Vec<(Compact<u16>, Compact<u16>)>, // Vec of (uid, weight)
    bonds: Vec<(Compact<u16>, Compact<u16>)>,   // Vec of (uid, bond)
    pruning_score: Compact<u16>,
}

#[freeze_struct("1d61b46ca68a1e02")]
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)]
pub struct NeuronInfoLite<AccountId: TypeInfo + Encode + Decode> {
    hotkey: AccountId,
    coldkey: AccountId,
    uid: Compact<u16>,
    netuid: Compact<NetUid>,
    active: bool,
    axon_info: AxonInfo,
    prometheus_info: PrometheusInfo,
    stake: Vec<(AccountId, Compact<AlphaBalance>)>, // map of coldkey to stake on this neuron/hotkey (includes delegations)
    rank: Compact<u16>,
    emission: Compact<AlphaBalance>,
    incentive: Compact<PerU16>,
    consensus: Compact<PerU16>,
    trust: Compact<PerU16>,
    validator_trust: Compact<PerU16>,
    dividends: Compact<PerU16>,
    last_update: Compact<u64>,
    validator_permit: bool,
    // has no weights or bonds
    pruning_score: Compact<u16>,
}

impl<T: Config> Pallet<T> {
    pub fn get_neurons(netuid: NetUid) -> Vec<NeuronInfo<T::AccountId>> {
        if !Self::if_subnet_exist(netuid) {
            return Vec::new();
        }

        let mut neurons = Vec::new();
        let n = Self::get_subnetwork_n(netuid);
        for uid in 0..n {
            let neuron = match Self::get_neuron_subnet_exists(netuid, uid) {
                Some(n) => n,
                None => break, // No more neurons
            };

            neurons.push(neuron);
        }
        neurons
    }

    fn get_neuron_subnet_exists(netuid: NetUid, uid: u16) -> Option<NeuronInfo<T::AccountId>> {
        let hotkey = match Self::get_hotkey_for_net_and_uid(netuid, uid) {
            Ok(h) => h,
            Err(_) => return None,
        };

        let axon_info = Self::get_axon_info(netuid, &hotkey.clone());

        let prometheus_info = Self::get_prometheus_info(netuid, &hotkey.clone());

        let coldkey = Owner::<T>::get(hotkey.clone()).clone();

        let active = Self::get_active_for_uid(netuid, uid);
        let emission = Self::get_emission_for_uid(netuid, uid);
        let incentive = Self::get_incentive_for_uid(netuid.into(), uid);
        let consensus = Self::get_consensus_for_uid(netuid, uid);
        let validator_trust = Self::get_validator_trust_for_uid(netuid, uid);
        let dividends = Self::get_dividends_for_uid(netuid, uid);
        let last_update = Self::get_last_update_for_uid(NetUidStorageIndex::from(netuid), uid);
        let validator_permit = Self::get_validator_permit_for_uid(netuid, uid);

        let weights = Weights::<T>::get(NetUidStorageIndex::from(netuid), uid)
            .into_iter()
            .filter_map(|(i, w)| {
                if w > 0 {
                    Some((i.into(), w.into()))
                } else {
                    None
                }
            })
            .collect::<Vec<(Compact<u16>, Compact<u16>)>>();

        let bonds = Bonds::<T>::get(NetUidStorageIndex::from(netuid), uid)
            .iter()
            .filter_map(|(i, b)| {
                if *b > 0 {
                    Some((i.into(), b.into()))
                } else {
                    None
                }
            })
            .collect::<Vec<(Compact<u16>, Compact<u16>)>>();
        let stake: Vec<(T::AccountId, Compact<AlphaBalance>)> = vec![(
            coldkey.clone(),
            Self::get_stake_for_hotkey_on_subnet(&hotkey, netuid).into(),
        )];
        let neuron = NeuronInfo {
            hotkey: hotkey.clone(),
            coldkey: coldkey.clone(),
            uid: uid.into(),
            netuid: netuid.into(),
            active,
            axon_info,
            prometheus_info,
            stake,
            rank: 0.into(), // Deprecated: no longer computed
            emission: emission.into(),
            incentive: PerU16::from_parts(incentive).into(),
            consensus: PerU16::from_parts(consensus).into(),
            trust: PerU16::zero().into(), // Deprecated: no longer computed
            validator_trust: PerU16::from_parts(validator_trust).into(),
            dividends: PerU16::from_parts(dividends).into(),
            last_update: last_update.into(),
            validator_permit,
            weights,
            bonds,
            pruning_score: u16::MAX.into(), // Deprecated: no longer computed
        };

        Some(neuron)
    }

    pub fn get_neuron(netuid: NetUid, uid: u16) -> Option<NeuronInfo<T::AccountId>> {
        if !Self::if_subnet_exist(netuid) {
            return None;
        }

        Self::get_neuron_subnet_exists(netuid, uid)
    }

    fn get_neuron_lite_subnet_exists(
        netuid: NetUid,
        uid: u16,
    ) -> Option<NeuronInfoLite<T::AccountId>> {
        let hotkey = match Self::get_hotkey_for_net_and_uid(netuid, uid) {
            Ok(h) => h,
            Err(_) => return None,
        };

        let axon_info = Self::get_axon_info(netuid, &hotkey.clone());

        let prometheus_info = Self::get_prometheus_info(netuid, &hotkey.clone());

        let coldkey = Owner::<T>::get(hotkey.clone()).clone();

        let active = Self::get_active_for_uid(netuid, uid);
        let emission = Self::get_emission_for_uid(netuid, uid);
        let incentive = Self::get_incentive_for_uid(netuid.into(), uid);
        let consensus = Self::get_consensus_for_uid(netuid, uid);
        let validator_trust = Self::get_validator_trust_for_uid(netuid, uid);
        let dividends = Self::get_dividends_for_uid(netuid, uid);
        let last_update = Self::get_last_update_for_uid(NetUidStorageIndex::from(netuid), uid);
        let validator_permit = Self::get_validator_permit_for_uid(netuid, uid);

        let stake: Vec<(T::AccountId, Compact<AlphaBalance>)> = vec![(
            coldkey.clone(),
            Self::get_stake_for_hotkey_on_subnet(&hotkey, netuid).into(),
        )];

        let neuron = NeuronInfoLite {
            hotkey: hotkey.clone(),
            coldkey: coldkey.clone(),
            uid: uid.into(),
            netuid: netuid.into(),
            active,
            axon_info,
            prometheus_info,
            stake,
            rank: 0.into(), // Deprecated: no longer computed
            emission: emission.into(),
            incentive: PerU16::from_parts(incentive).into(),
            consensus: PerU16::from_parts(consensus).into(),
            trust: PerU16::zero().into(), // Deprecated: no longer computed
            validator_trust: PerU16::from_parts(validator_trust).into(),
            dividends: PerU16::from_parts(dividends).into(),
            last_update: last_update.into(),
            validator_permit,
            pruning_score: u16::MAX.into(), // Deprecated: no longer computed
        };

        Some(neuron)
    }

    pub fn get_neurons_lite(netuid: NetUid) -> Vec<NeuronInfoLite<T::AccountId>> {
        if !Self::if_subnet_exist(netuid) {
            return Vec::new();
        }

        let mut neurons: Vec<NeuronInfoLite<T::AccountId>> = Vec::new();
        let n = Self::get_subnetwork_n(netuid);
        for uid in 0..n {
            let neuron = match Self::get_neuron_lite_subnet_exists(netuid, uid) {
                Some(n) => n,
                None => break, // No more neurons
            };

            neurons.push(neuron);
        }
        neurons
    }

    pub fn get_neuron_lite(netuid: NetUid, uid: u16) -> Option<NeuronInfoLite<T::AccountId>> {
        if !Self::if_subnet_exist(netuid) {
            return None;
        }

        Self::get_neuron_lite_subnet_exists(netuid, uid)
    }
}