diff --git a/Cargo.lock b/Cargo.lock index 42522da321..a224a12432 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11160,8 +11160,10 @@ version = "0.0.2" dependencies = [ "frame-support", "pallet-subtensor", + "parity-scale-codec", "serde", "sp-api", + "sp-runtime", ] [[package]] diff --git a/pallets/subtensor/rpc/Cargo.toml b/pallets/subtensor/rpc/Cargo.toml index 861c313d8f..c2d631e1a5 100644 --- a/pallets/subtensor/rpc/Cargo.toml +++ b/pallets/subtensor/rpc/Cargo.toml @@ -12,9 +12,7 @@ publish = false workspace = true [dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ - "derive", -] } +codec = { workspace = true } jsonrpsee = { workspace = true, features = ["client-core", "server", "macros"] } serde = { workspace = true, features = ["derive"] } diff --git a/pallets/subtensor/rpc/src/lib.rs b/pallets/subtensor/rpc/src/lib.rs index cdbcebcacb..7233a16c75 100644 --- a/pallets/subtensor/rpc/src/lib.rs +++ b/pallets/subtensor/rpc/src/lib.rs @@ -1,12 +1,13 @@ //! RPC interface for the custom Subtensor rpc methods +use codec::{Decode, Encode}; use jsonrpsee::{ core::RpcResult, proc_macros::rpc, types::{error::ErrorObject, ErrorObjectOwned}, }; use sp_blockchain::HeaderBackend; -use sp_runtime::traits::Block as BlockT; +use sp_runtime::{traits::Block as BlockT, AccountId32}; use std::sync::Arc; use sp_api::ProvideRuntimeApi; @@ -116,9 +117,12 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_delegates(at).map_err(|e| { - Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into() - }) + match api.get_delegates(at) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into()) + } + } } fn get_delegate( @@ -129,9 +133,20 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_delegate(at, delegate_account_vec).map_err(|e| { - Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into() - }) + let delegate_account = match AccountId32::decode(&mut &delegate_account_vec[..]) { + Ok(delegate_account) => delegate_account, + Err(e) => { + return Err( + Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into(), + ) + } + }; + match api.get_delegate(at, delegate_account) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into()) + } + } } fn get_delegated( @@ -142,9 +157,20 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_delegated(at, delegatee_account_vec).map_err(|e| { - Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into() - }) + let delegatee_account = match AccountId32::decode(&mut &delegatee_account_vec[..]) { + Ok(delegatee_account) => delegatee_account, + Err(e) => { + return Err( + Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into(), + ) + } + }; + match api.get_delegated(at, delegatee_account) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get delegates info: {:?}", e)).into()) + } + } } fn get_neurons_lite( @@ -155,9 +181,12 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_neurons_lite(at, netuid).map_err(|e| { - Error::RuntimeError(format!("Unable to get neurons lite info: {:?}", e)).into() - }) + match api.get_neurons_lite(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get neurons lite info: {:?}", e)).into()) + } + } } fn get_neuron_lite( @@ -169,17 +198,24 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_neuron_lite(at, netuid, uid).map_err(|e| { - Error::RuntimeError(format!("Unable to get neurons lite info: {:?}", e)).into() - }) + match api.get_neuron_lite(at, netuid, uid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get neurons lite info: {:?}", e)).into()) + } + } } fn get_neurons(&self, netuid: u16, at: Option<::Hash>) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_neurons(at, netuid) - .map_err(|e| Error::RuntimeError(format!("Unable to get neurons info: {:?}", e)).into()) + match api.get_neurons(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get neurons info: {:?}", e)).into()) + } + } } fn get_neuron( @@ -191,8 +227,12 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_neuron(at, netuid, uid) - .map_err(|e| Error::RuntimeError(format!("Unable to get neuron info: {:?}", e)).into()) + match api.get_neuron(at, netuid, uid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get neuron info: {:?}", e)).into()) + } + } } fn get_subnet_info( @@ -203,8 +243,12 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_subnet_info(at, netuid) - .map_err(|e| Error::RuntimeError(format!("Unable to get subnet info: {:?}", e)).into()) + match api.get_subnet_info(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get subnet info: {:?}", e)).into()) + } + } } fn get_subnet_hyperparams( @@ -215,23 +259,36 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_subnet_hyperparams(at, netuid) - .map_err(|e| Error::RuntimeError(format!("Unable to get subnet info: {:?}", e)).into()) + match api.get_subnet_hyperparams(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get subnet info: {:?}", e)).into()) + } + } } fn get_all_dynamic_info(&self, at: Option<::Hash>) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_all_dynamic_info(at).map_err(|e| { - Error::RuntimeError(format!("Unable to get dynamic subnets info: {:?}", e)).into() - }) + + match api.get_all_dynamic_info(at) { + Ok(result) => Ok(result.encode()), + Err(e) => Err(Error::RuntimeError(format!( + "Unable to get dynamic subnets info: {:?}", + e + )) + .into()), + } } fn get_all_metagraphs(&self, at: Option<::Hash>) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_all_metagraphs(at) - .map_err(|e| Error::RuntimeError(format!("Unable to get metagraps: {:?}", e)).into()) + + match api.get_all_metagraphs(at) { + Ok(result) => Ok(result.encode()), + Err(e) => Err(Error::RuntimeError(format!("Unable to get metagraps: {:?}", e)).into()), + } } fn get_dynamic_info( @@ -241,9 +298,15 @@ where ) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_dynamic_info(at, netuid).map_err(|e| { - Error::RuntimeError(format!("Unable to get dynamic subnets info: {:?}", e)).into() - }) + + match api.get_dynamic_info(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => Err(Error::RuntimeError(format!( + "Unable to get dynamic subnets info: {:?}", + e + )) + .into()), + } } fn get_metagraph( @@ -253,9 +316,14 @@ where ) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_metagraph(at, netuid).map_err(|e| { - Error::RuntimeError(format!("Unable to get dynamic subnets info: {:?}", e)).into() - }) + match api.get_metagraph(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => Err(Error::RuntimeError(format!( + "Unable to get dynamic subnets info: {:?}", + e + )) + .into()), + } } fn get_subnet_state( @@ -265,17 +333,25 @@ where ) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_subnet_state(at, netuid).map_err(|e| { - Error::RuntimeError(format!("Unable to get subnet state info: {:?}", e)).into() - }) + + match api.get_subnet_state(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get subnet state info: {:?}", e)).into()) + } + } } fn get_subnets_info(&self, at: Option<::Hash>) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_subnets_info(at) - .map_err(|e| Error::RuntimeError(format!("Unable to get subnets info: {:?}", e)).into()) + match api.get_subnets_info(at) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get subnets info: {:?}", e)).into()) + } + } } fn get_subnet_info_v2( @@ -286,16 +362,24 @@ where let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_subnet_info_v2(at, netuid) - .map_err(|e| Error::RuntimeError(format!("Unable to get subnet info: {:?}", e)).into()) + match api.get_subnet_info_v2(at, netuid) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get subnet info: {:?}", e)).into()) + } + } } fn get_subnets_info_v2(&self, at: Option<::Hash>) -> RpcResult> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_subnets_info_v2(at) - .map_err(|e| Error::RuntimeError(format!("Unable to get subnets info: {:?}", e)).into()) + match api.get_subnets_info_v2(at) { + Ok(result) => Ok(result.encode()), + Err(e) => { + Err(Error::RuntimeError(format!("Unable to get subnets info: {:?}", e)).into()) + } + } } fn get_network_lock_cost(&self, at: Option<::Hash>) -> RpcResult { diff --git a/pallets/subtensor/runtime-api/Cargo.toml b/pallets/subtensor/runtime-api/Cargo.toml index ef3e04947d..a5300d7599 100644 --- a/pallets/subtensor/runtime-api/Cargo.toml +++ b/pallets/subtensor/runtime-api/Cargo.toml @@ -13,9 +13,10 @@ workspace = true [dependencies] sp-api = { workspace = true } +sp-runtime = { workspace = true } frame-support = { workspace = true } serde = { workspace = true, features = ["derive"] } - +codec = { workspace = true } # local pallet-subtensor = { version = "4.0.0-dev", path = "../../subtensor", default-features = false } @@ -23,8 +24,10 @@ pallet-subtensor = { version = "4.0.0-dev", path = "../../subtensor", default-fe default = ["std"] std = [ "sp-api/std", + "sp-runtime/std", "frame-support/std", "pallet-subtensor/std", - "serde/std" + "serde/std", + "codec/std" ] pow-faucet = [] diff --git a/pallets/subtensor/runtime-api/src/lib.rs b/pallets/subtensor/runtime-api/src/lib.rs index 31f351aeb6..9f6d960407 100644 --- a/pallets/subtensor/runtime-api/src/lib.rs +++ b/pallets/subtensor/runtime-api/src/lib.rs @@ -1,40 +1,51 @@ #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; use alloc::vec::Vec; +use codec::Compact; +use pallet_subtensor::rpc_info::{ + delegate_info::DelegateInfo, + dynamic_info::DynamicInfo, + metagraph::Metagraph, + neuron_info::{NeuronInfo, NeuronInfoLite}, + show_subnet::SubnetState, + stake_info::StakeInfo, + subnet_info::{SubnetHyperparams, SubnetInfo, SubnetInfov2}, +}; +use sp_runtime::AccountId32; // Here we declare the runtime API. It is implemented it the `impl` block in // src/neuron_info.rs, src/subnet_info.rs, and src/delegate_info.rs sp_api::decl_runtime_apis! { pub trait DelegateInfoRuntimeApi { - fn get_delegates() -> Vec; - fn get_delegate( delegate_account_vec: Vec ) -> Vec; - fn get_delegated( delegatee_account_vec: Vec ) -> Vec; + fn get_delegates() -> Vec>; + fn get_delegate( delegate_account: AccountId32 ) -> Option>; + fn get_delegated( delegatee_account: AccountId32 ) -> Vec<(DelegateInfo, Compact)>; } pub trait NeuronInfoRuntimeApi { - fn get_neurons(netuid: u16) -> Vec; - fn get_neuron(netuid: u16, uid: u16) -> Vec; - fn get_neurons_lite(netuid: u16) -> Vec; - fn get_neuron_lite(netuid: u16, uid: u16) -> Vec; + fn get_neurons(netuid: u16) -> Vec>; + fn get_neuron(netuid: u16, uid: u16) -> Option>; + fn get_neurons_lite(netuid: u16) -> Vec>; + fn get_neuron_lite(netuid: u16, uid: u16) -> Option>; } pub trait SubnetInfoRuntimeApi { - fn get_subnet_info(netuid: u16) -> Vec; - fn get_subnets_info() -> Vec; - fn get_subnet_info_v2(netuid: u16) -> Vec; - fn get_subnets_info_v2() -> Vec; - fn get_subnet_hyperparams(netuid: u16) -> Vec; - fn get_all_dynamic_info() -> Vec; - fn get_all_metagraphs() -> Vec; - fn get_metagraph(netuid: u16) -> Vec; - fn get_dynamic_info(netuid: u16) -> Vec; - fn get_subnet_state(netuid: u16) -> Vec; + fn get_subnet_info(netuid: u16) -> Option>; + fn get_subnets_info() -> Vec>>; + fn get_subnet_info_v2(netuid: u16) -> Option>; + fn get_subnets_info_v2() -> Vec>>; + fn get_subnet_hyperparams(netuid: u16) -> Option; + fn get_all_dynamic_info() -> Vec>>; + fn get_all_metagraphs() -> Vec>>; + fn get_metagraph(netuid: u16) -> Option>; + fn get_dynamic_info(netuid: u16) -> Option>; + fn get_subnet_state(netuid: u16) -> Option>; } pub trait StakeInfoRuntimeApi { - fn get_stake_info_for_coldkey( coldkey_account_vec: Vec ) -> Vec; - fn get_stake_info_for_coldkeys( coldkey_account_vecs: Vec> ) -> Vec; - fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account_vec: Vec, coldkey_account_vec: Vec, netuid: u16 ) -> Vec; + fn get_stake_info_for_coldkey( coldkey_account: AccountId32 ) -> Vec>; + fn get_stake_info_for_coldkeys( coldkey_accounts: Vec ) -> Vec<(AccountId32, Vec>)>; + fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account: AccountId32, coldkey_account: AccountId32, netuid: u16 ) -> Option>; } pub trait SubnetRegistrationRuntimeApi { diff --git a/pallets/subtensor/src/rpc_info/delegate_info.rs b/pallets/subtensor/src/rpc_info/delegate_info.rs index f8d6418232..acfe28b43d 100644 --- a/pallets/subtensor/src/rpc_info/delegate_info.rs +++ b/pallets/subtensor/src/rpc_info/delegate_info.rs @@ -6,15 +6,14 @@ use safe_math::*; use substrate_fixed::types::U64F64; extern crate alloc; use codec::Compact; -use sp_core::hexdisplay::AsBytesRef; -#[freeze_struct("5752e4c650a83e0d")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct DelegateInfo { - delegate_ss58: T::AccountId, +#[freeze_struct("66105c2cfec0608d")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct DelegateInfo { + delegate_ss58: AccountId, take: Compact, - nominators: Vec<(T::AccountId, Compact)>, // map of nominator_ss58 to stake amount - owner_ss58: T::AccountId, + nominators: Vec<(AccountId, Compact)>, // map of nominator_ss58 to 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 return_per_1000: Compact, // Delegators current daily return per 1000 TAO staked minus take fee @@ -50,7 +49,7 @@ impl Pallet { Self::return_per_1000_tao(take, total_stake, emissions_per_day) } - fn get_delegate_by_existing_account(delegate: AccountIdOf) -> DelegateInfo { + fn get_delegate_by_existing_account(delegate: AccountIdOf) -> DelegateInfo { let mut nominators = Vec::<(T::AccountId, Compact)>::new(); for (nominator, stake) in @@ -107,13 +106,7 @@ impl Pallet { } } - pub fn get_delegate(delegate_account_vec: Vec) -> Option> { - if delegate_account_vec.len() != 32 { - return None; - } - - let delegate: AccountIdOf = - T::AccountId::decode(&mut delegate_account_vec.as_bytes_ref()).ok()?; + pub fn get_delegate(delegate: T::AccountId) -> Option> { // Check delegate exists if !>::contains_key(delegate.clone()) { return None; @@ -125,8 +118,8 @@ impl Pallet { /// get all delegates info from storage /// - pub fn get_delegates() -> Vec> { - let mut delegates = Vec::>::new(); + 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()); delegates.push(delegate_info); @@ -137,12 +130,10 @@ impl Pallet { /// get all delegate info and staked token amount for a given delegatee account /// - pub fn get_delegated(delegatee_account_vec: Vec) -> Vec<(DelegateInfo, Compact)> { - let Ok(delegatee) = T::AccountId::decode(&mut delegatee_account_vec.as_bytes_ref()) else { - return Vec::new(); // No delegates for invalid account - }; - - let mut delegates: Vec<(DelegateInfo, Compact)> = Vec::new(); + pub fn get_delegated( + delegatee: T::AccountId, + ) -> Vec<(DelegateInfo, Compact)> { + let mut delegates: Vec<(DelegateInfo, 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()); diff --git a/pallets/subtensor/src/rpc_info/dynamic_info.rs b/pallets/subtensor/src/rpc_info/dynamic_info.rs index 27d10dc2d7..bd24844e1a 100644 --- a/pallets/subtensor/src/rpc_info/dynamic_info.rs +++ b/pallets/subtensor/src/rpc_info/dynamic_info.rs @@ -4,12 +4,12 @@ use codec::Compact; use frame_support::pallet_prelude::{Decode, Encode}; use subtensor_macros::freeze_struct; -#[freeze_struct("a5cdc80d655398e9")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct DynamicInfo { +#[freeze_struct("70be0b07db585696")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct DynamicInfo { netuid: Compact, - owner_hotkey: T::AccountId, - owner_coldkey: T::AccountId, + owner_hotkey: AccountId, + owner_coldkey: AccountId, subnet_name: Vec>, token_symbol: Vec>, tempo: Compact, @@ -30,7 +30,7 @@ pub struct DynamicInfo { } impl Pallet { - pub fn get_dynamic_info(netuid: u16) -> Option> { + pub fn get_dynamic_info(netuid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; } @@ -66,9 +66,9 @@ impl Pallet { subnet_identity: SubnetIdentities::::get(netuid), }) } - pub fn get_all_dynamic_info() -> Vec>> { + pub fn get_all_dynamic_info() -> Vec>> { let netuids: Vec = Self::get_all_subnet_netuids(); - let mut dynamic_info = Vec::>>::new(); + let mut dynamic_info = Vec::>>::new(); for netuid in netuids.clone().iter() { dynamic_info.push(Self::get_dynamic_info(*netuid)); } diff --git a/pallets/subtensor/src/rpc_info/metagraph.rs b/pallets/subtensor/src/rpc_info/metagraph.rs index 267af1d050..69b21b0e9f 100644 --- a/pallets/subtensor/src/rpc_info/metagraph.rs +++ b/pallets/subtensor/src/rpc_info/metagraph.rs @@ -6,9 +6,9 @@ use frame_support::pallet_prelude::{Decode, Encode}; use substrate_fixed::types::I64F64; use subtensor_macros::freeze_struct; -#[freeze_struct("7c5fe907490c5d5e")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct Metagraph { +#[freeze_struct("a92e51d2046f4be8")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct Metagraph { // Subnet index netuid: Compact, @@ -19,8 +19,8 @@ pub struct Metagraph { network_registered_at: Compact, // block at registration // Keys for owner. - owner_hotkey: T::AccountId, // hotkey - owner_coldkey: T::AccountId, // coldkey. + owner_hotkey: AccountId, // hotkey + owner_coldkey: AccountId, // coldkey. // Tempo terms. block: Compact, // block at call. @@ -81,8 +81,8 @@ pub struct Metagraph { bonds_moving_avg: Compact, // Bonds moving avg // Metagraph info. - hotkeys: Vec, // hotkey per UID - coldkeys: Vec, // coldkey per UID + hotkeys: Vec, // hotkey per UID + coldkeys: Vec, // coldkey per UID identities: Vec>, // coldkeys identities axons: Vec, // UID axons. active: Vec, // Avtive per UID @@ -101,12 +101,12 @@ pub struct Metagraph { total_stake: Vec>, // Total stake per UID // Dividend break down. - tao_dividends_per_hotkey: Vec<(T::AccountId, Compact)>, // List of dividend payouts in tao via root. - alpha_dividends_per_hotkey: Vec<(T::AccountId, Compact)>, // List of dividend payout in alpha via subnet. + tao_dividends_per_hotkey: Vec<(AccountId, Compact)>, // List of dividend payouts in tao via root. + alpha_dividends_per_hotkey: Vec<(AccountId, Compact)>, // List of dividend payout in alpha via subnet. } impl Pallet { - pub fn get_metagraph(netuid: u16) -> Option> { + pub fn get_metagraph(netuid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; } @@ -280,9 +280,9 @@ impl Pallet { alpha_dividends_per_hotkey, }) } - pub fn get_all_metagraphs() -> Vec>> { + pub fn get_all_metagraphs() -> Vec>> { let netuids: Vec = Self::get_all_subnet_netuids(); - let mut metagraphs = Vec::>>::new(); + let mut metagraphs = Vec::>>::new(); for netuid in netuids.clone().iter() { metagraphs.push(Self::get_metagraph(*netuid)); } diff --git a/pallets/subtensor/src/rpc_info/neuron_info.rs b/pallets/subtensor/src/rpc_info/neuron_info.rs index be367a5669..4838b376f9 100644 --- a/pallets/subtensor/src/rpc_info/neuron_info.rs +++ b/pallets/subtensor/src/rpc_info/neuron_info.rs @@ -3,17 +3,17 @@ use frame_support::pallet_prelude::{Decode, Encode}; extern crate alloc; use codec::Compact; -#[freeze_struct("45e69321f5c74b4b")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct NeuronInfo { - hotkey: T::AccountId, - coldkey: T::AccountId, +#[freeze_struct("d6da7340b3350951")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct NeuronInfo { + hotkey: AccountId, + coldkey: AccountId, uid: Compact, netuid: Compact, active: bool, axon_info: AxonInfo, prometheus_info: PrometheusInfo, - stake: Vec<(T::AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) + stake: Vec<(AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) rank: Compact, emission: Compact, incentive: Compact, @@ -28,17 +28,17 @@ pub struct NeuronInfo { pruning_score: Compact, } -#[freeze_struct("c21f0f4f22bcb2a1")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct NeuronInfoLite { - hotkey: T::AccountId, - coldkey: T::AccountId, +#[freeze_struct("3e9eed057f379b3b")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct NeuronInfoLite { + hotkey: AccountId, + coldkey: AccountId, uid: Compact, netuid: Compact, active: bool, axon_info: AxonInfo, prometheus_info: PrometheusInfo, - stake: Vec<(T::AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) + stake: Vec<(AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) rank: Compact, emission: Compact, incentive: Compact, @@ -53,7 +53,7 @@ pub struct NeuronInfoLite { } impl Pallet { - pub fn get_neurons(netuid: u16) -> Vec> { + pub fn get_neurons(netuid: u16) -> Vec> { if !Self::if_subnet_exist(netuid) { return Vec::new(); } @@ -71,7 +71,7 @@ impl Pallet { neurons } - fn get_neuron_subnet_exists(netuid: u16, uid: u16) -> Option> { + fn get_neuron_subnet_exists(netuid: u16, uid: u16) -> Option> { let hotkey = match Self::get_hotkey_for_net_and_uid(netuid, uid) { Ok(h) => h, Err(_) => return None, @@ -146,7 +146,7 @@ impl Pallet { Some(neuron) } - pub fn get_neuron(netuid: u16, uid: u16) -> Option> { + pub fn get_neuron(netuid: u16, uid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; } @@ -154,7 +154,10 @@ impl Pallet { Self::get_neuron_subnet_exists(netuid, uid) } - fn get_neuron_lite_subnet_exists(netuid: u16, uid: u16) -> Option> { + fn get_neuron_lite_subnet_exists( + netuid: u16, + uid: u16, + ) -> Option> { let hotkey = match Self::get_hotkey_for_net_and_uid(netuid, uid) { Ok(h) => h, Err(_) => return None, @@ -207,12 +210,12 @@ impl Pallet { Some(neuron) } - pub fn get_neurons_lite(netuid: u16) -> Vec> { + pub fn get_neurons_lite(netuid: u16) -> Vec> { if !Self::if_subnet_exist(netuid) { return Vec::new(); } - let mut neurons: Vec> = Vec::new(); + let mut neurons: Vec> = 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) { @@ -225,7 +228,7 @@ impl Pallet { neurons } - pub fn get_neuron_lite(netuid: u16, uid: u16) -> Option> { + pub fn get_neuron_lite(netuid: u16, uid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; } diff --git a/pallets/subtensor/src/rpc_info/show_subnet.rs b/pallets/subtensor/src/rpc_info/show_subnet.rs index b10a193598..9b66439fa2 100644 --- a/pallets/subtensor/src/rpc_info/show_subnet.rs +++ b/pallets/subtensor/src/rpc_info/show_subnet.rs @@ -5,12 +5,12 @@ use codec::Compact; use frame_support::pallet_prelude::{Decode, Encode}; use substrate_fixed::types::I64F64; -#[freeze_struct("1af112d561741563")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct SubnetState { +#[freeze_struct("7954f39fd0755b28")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct SubnetState { netuid: Compact, - hotkeys: Vec, - coldkeys: Vec, + hotkeys: Vec, + coldkeys: Vec, active: Vec, validator_permit: Vec, pruning_score: Vec>, @@ -77,9 +77,9 @@ impl Pallet { /// /// # Returns /// - /// * `Option>` - An optional `SubnetState` struct containing the collected data for the subnet. + /// * `Option>` - 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: u16) -> Option> { + pub fn get_subnet_state(netuid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; } diff --git a/pallets/subtensor/src/rpc_info/stake_info.rs b/pallets/subtensor/src/rpc_info/stake_info.rs index 0422bc33b8..631e3a167a 100644 --- a/pallets/subtensor/src/rpc_info/stake_info.rs +++ b/pallets/subtensor/src/rpc_info/stake_info.rs @@ -2,13 +2,12 @@ use super::*; use frame_support::pallet_prelude::{Decode, Encode}; extern crate alloc; use codec::Compact; -use sp_core::hexdisplay::AsBytesRef; -#[freeze_struct("c5e3871b39062f8e")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct StakeInfo { - hotkey: T::AccountId, - coldkey: T::AccountId, +#[freeze_struct("4f16c654467bc8b6")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct StakeInfo { + hotkey: AccountId, + coldkey: AccountId, netuid: Compact, stake: Compact, locked: Compact, @@ -20,16 +19,16 @@ pub struct StakeInfo { impl Pallet { fn _get_stake_info_for_coldkeys( coldkeys: Vec, - ) -> Vec<(T::AccountId, Vec>)> { + ) -> Vec<(T::AccountId, Vec>)> { if coldkeys.is_empty() { return Vec::new(); // No coldkeys to check } let netuids: Vec = Self::get_all_subnet_netuids(); - let mut stake_info: Vec<(T::AccountId, Vec>)> = Vec::new(); + let mut stake_info: Vec<(T::AccountId, Vec>)> = Vec::new(); for coldkey_i in coldkeys.clone().iter() { // Get all hotkeys associated with this coldkey. let staking_hotkeys = StakingHotkeys::::get(coldkey_i.clone()); - let mut stake_info_for_coldkey: Vec> = Vec::new(); + let mut stake_info_for_coldkey: Vec> = Vec::new(); for netuid_i in netuids.clone().iter() { for hotkey_i in staking_hotkeys.clone().iter() { let alpha: u64 = Self::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -59,35 +58,19 @@ impl Pallet { } pub fn get_stake_info_for_coldkeys( - coldkey_account_vecs: Vec>, - ) -> Vec<(T::AccountId, Vec>)> { - let mut coldkeys: Vec = Vec::new(); - for coldkey_account_vec in coldkey_account_vecs { - if coldkey_account_vec.len() != 32 { - continue; // Invalid coldkey - } - let Ok(coldkey) = T::AccountId::decode(&mut coldkey_account_vec.as_bytes_ref()) else { - continue; - }; - coldkeys.push(coldkey); + coldkey_accounts: Vec, + ) -> Vec<(T::AccountId, Vec>)> { + if coldkey_accounts.is_empty() { + return Vec::new(); // Empty coldkeys } - if coldkeys.is_empty() { - return Vec::new(); // Invalid coldkey - } - - Self::_get_stake_info_for_coldkeys(coldkeys) + Self::_get_stake_info_for_coldkeys(coldkey_accounts) } - pub fn get_stake_info_for_coldkey(coldkey_account_vec: Vec) -> Vec> { - if coldkey_account_vec.len() != 32 { - return Vec::new(); // Invalid coldkey - } - - let Ok(coldkey) = T::AccountId::decode(&mut coldkey_account_vec.as_bytes_ref()) else { - return Vec::new(); - }; - let stake_info = Self::_get_stake_info_for_coldkeys(vec![coldkey]); + pub fn get_stake_info_for_coldkey( + coldkey_account: T::AccountId, + ) -> Vec> { + let stake_info = Self::_get_stake_info_for_coldkeys(vec![coldkey_account]); if stake_info.is_empty() { Vec::new() // Invalid coldkey @@ -101,34 +84,21 @@ impl Pallet { } pub fn get_stake_info_for_hotkey_coldkey_netuid( - hotkey_account_vec: Vec, - coldkey_account_vec: Vec, + hotkey_account: T::AccountId, + coldkey_account: T::AccountId, netuid: u16, - ) -> Option> { - if coldkey_account_vec.len() != 32 { - return None; // Invalid coldkey - } - - let Ok(coldkey) = T::AccountId::decode(&mut coldkey_account_vec.as_bytes_ref()) else { - return None; - }; - - if hotkey_account_vec.len() != 32 { - return None; // Invalid hotkey - } - - let Ok(hotkey) = T::AccountId::decode(&mut hotkey_account_vec.as_bytes_ref()) else { - return None; - }; - - let alpha: u64 = - Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); - let emission: u64 = AlphaDividendsPerSubnet::::get(netuid, &hotkey); - let is_registered: bool = Self::is_hotkey_registered_on_network(netuid, &hotkey); + ) -> Option> { + let alpha: u64 = Self::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account, + &coldkey_account, + netuid, + ); + let emission: u64 = AlphaDividendsPerSubnet::::get(netuid, &hotkey_account); + let is_registered: bool = Self::is_hotkey_registered_on_network(netuid, &hotkey_account); Some(StakeInfo { - hotkey: hotkey.clone(), - coldkey: coldkey.clone(), + hotkey: hotkey_account, + coldkey: coldkey_account, netuid: (netuid).into(), stake: alpha.into(), locked: 0.into(), diff --git a/pallets/subtensor/src/rpc_info/subnet_info.rs b/pallets/subtensor/src/rpc_info/subnet_info.rs index bdd420821a..2d9e3dfa48 100644 --- a/pallets/subtensor/src/rpc_info/subnet_info.rs +++ b/pallets/subtensor/src/rpc_info/subnet_info.rs @@ -4,9 +4,9 @@ use frame_support::storage::IterableStorageMap; extern crate alloc; use codec::Compact; -#[freeze_struct("fe79d58173da662a")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct SubnetInfo { +#[freeze_struct("1eee6f3911800c6b")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct SubnetInfo { netuid: Compact, rho: Compact, kappa: Compact, @@ -24,12 +24,12 @@ pub struct SubnetInfo { network_connect: Vec<[u16; 2]>, emission_values: Compact, burn: Compact, - owner: T::AccountId, + owner: AccountId, } -#[freeze_struct("65f931972fa13222")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] -pub struct SubnetInfov2 { +#[freeze_struct("ae2cf407a8d95ef6")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct SubnetInfov2 { netuid: Compact, rho: Compact, kappa: Compact, @@ -47,12 +47,12 @@ pub struct SubnetInfov2 { network_connect: Vec<[u16; 2]>, emission_values: Compact, burn: Compact, - owner: T::AccountId, + owner: AccountId, identity: Option, } -#[freeze_struct("55b472510f10e76a")] -#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] +#[freeze_struct("4714b5e2336f7b19")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SubnetHyperparams { rho: Compact, kappa: Compact, @@ -84,7 +84,7 @@ pub struct SubnetHyperparams { } impl Pallet { - pub fn get_subnet_info(netuid: u16) -> Option> { + pub fn get_subnet_info(netuid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; } @@ -132,7 +132,7 @@ impl Pallet { }) } - pub fn get_subnets_info() -> Vec>> { + pub fn get_subnets_info() -> Vec>> { let mut subnet_netuids = Vec::::new(); let mut max_netuid: u16 = 0; for (netuid, added) in as IterableStorageMap>::iter() { @@ -144,7 +144,7 @@ impl Pallet { } } - let mut subnets_info = Vec::>>::new(); + let mut subnets_info = Vec::>>::new(); for netuid_ in 0..=max_netuid { if subnet_netuids.contains(&netuid_) { subnets_info.push(Self::get_subnet_info(netuid_)); @@ -154,7 +154,7 @@ impl Pallet { subnets_info } - pub fn get_subnet_info_v2(netuid: u16) -> Option> { + pub fn get_subnet_info_v2(netuid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; } @@ -204,7 +204,8 @@ impl Pallet { identity, }) } - pub fn get_subnets_info_v2() -> Vec>> { + + pub fn get_subnets_info_v2() -> Vec>> { let mut subnet_netuids = Vec::::new(); let mut max_netuid: u16 = 0; for (netuid, added) in as IterableStorageMap>::iter() { @@ -216,15 +217,16 @@ impl Pallet { } } - let mut subnets_info = Vec::>>::new(); + let mut subnets_info = Vec::>>::new(); for netuid_ in 0..=max_netuid { if subnet_netuids.contains(&netuid_) { - subnets_info.push(Self::get_subnet_info(netuid_)); + subnets_info.push(Self::get_subnet_info_v2(netuid_)); } } subnets_info } + pub fn get_subnet_hyperparams(netuid: u16) -> Option { if !Self::if_subnet_exist(netuid) { return None; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index d9c4fcd99d..1d2c154bcb 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -11,7 +11,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod check_nonce; mod migrations; -use codec::{Decode, Encode, MaxEncodedLen}; +use codec::{Compact, Decode, Encode, MaxEncodedLen}; use frame_support::traits::Imbalance; use frame_support::{ dispatch::DispatchResultWithPostInfo, @@ -30,6 +30,15 @@ use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; use pallet_registry::CanRegisterIdentity; +use pallet_subtensor::rpc_info::{ + delegate_info::DelegateInfo, + dynamic_info::DynamicInfo, + metagraph::Metagraph, + neuron_info::{NeuronInfo, NeuronInfoLite}, + show_subnet::SubnetState, + stake_info::StakeInfo, + subnet_info::{SubnetHyperparams, SubnetInfo, SubnetInfov2}, +}; use scale_info::TypeInfo; use smallvec::smallvec; use sp_api::impl_runtime_apis; @@ -220,7 +229,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 225, + spec_version: 226, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -2012,155 +2021,90 @@ impl_runtime_apis! { } impl subtensor_custom_rpc_runtime_api::DelegateInfoRuntimeApi for Runtime { - fn get_delegates() -> Vec { - let result = SubtensorModule::get_delegates(); - result.encode() + fn get_delegates() -> Vec> { + SubtensorModule::get_delegates() } - fn get_delegate(delegate_account_vec: Vec) -> Vec { - let _result = SubtensorModule::get_delegate(delegate_account_vec); - if _result.is_some() { - let result = _result.expect("Could not get DelegateInfo"); - result.encode() - } else { - vec![] - } + fn get_delegate(delegate_account: AccountId32) -> Option> { + SubtensorModule::get_delegate(delegate_account) } - fn get_delegated(delegatee_account_vec: Vec) -> Vec { - let result = SubtensorModule::get_delegated(delegatee_account_vec); - result.encode() + fn get_delegated(delegatee_account: AccountId32) -> Vec<(DelegateInfo, Compact)> { + SubtensorModule::get_delegated(delegatee_account) } } impl subtensor_custom_rpc_runtime_api::NeuronInfoRuntimeApi for Runtime { - fn get_neurons_lite(netuid: u16) -> Vec { - let result = SubtensorModule::get_neurons_lite(netuid); - result.encode() + fn get_neurons_lite(netuid: u16) -> Vec> { + SubtensorModule::get_neurons_lite(netuid) } - fn get_neuron_lite(netuid: u16, uid: u16) -> Vec { - let _result = SubtensorModule::get_neuron_lite(netuid, uid); - if _result.is_some() { - let result = _result.expect("Could not get NeuronInfoLite"); - result.encode() - } else { - vec![] - } + fn get_neuron_lite(netuid: u16, uid: u16) -> Option> { + SubtensorModule::get_neuron_lite(netuid, uid) } - fn get_neurons(netuid: u16) -> Vec { - let result = SubtensorModule::get_neurons(netuid); - result.encode() + fn get_neurons(netuid: u16) -> Vec> { + SubtensorModule::get_neurons(netuid) } - fn get_neuron(netuid: u16, uid: u16) -> Vec { - let _result = SubtensorModule::get_neuron(netuid, uid); - if _result.is_some() { - let result = _result.expect("Could not get NeuronInfo"); - result.encode() - } else { - vec![] - } + fn get_neuron(netuid: u16, uid: u16) -> Option> { + SubtensorModule::get_neuron(netuid, uid) } } impl subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi for Runtime { - fn get_subnet_info(netuid: u16) -> Vec { - let _result = SubtensorModule::get_subnet_info(netuid); - if _result.is_some() { - let result = _result.expect("Could not get SubnetInfo"); - result.encode() - } else { - vec![] - } + fn get_subnet_info(netuid: u16) -> Option> { + SubtensorModule::get_subnet_info(netuid) } - fn get_subnets_info() -> Vec { - let result = SubtensorModule::get_subnets_info(); - result.encode() + fn get_subnets_info() -> Vec>> { + SubtensorModule::get_subnets_info() } - fn get_subnet_info_v2(netuid: u16) -> Vec { - let _result = SubtensorModule::get_subnet_info_v2(netuid); - if _result.is_some() { - let result = _result.expect("Could not get SubnetInfo"); - result.encode() - } else { - vec![] - } + fn get_subnet_info_v2(netuid: u16) -> Option> { + SubtensorModule::get_subnet_info_v2(netuid) } - fn get_subnets_info_v2() -> Vec { - let result = SubtensorModule::get_subnets_info_v2(); - result.encode() + fn get_subnets_info_v2() -> Vec>> { + SubtensorModule::get_subnets_info_v2() } - fn get_subnet_hyperparams(netuid: u16) -> Vec { - let _result = SubtensorModule::get_subnet_hyperparams(netuid); - if _result.is_some() { - let result = _result.expect("Could not get SubnetHyperparams"); - result.encode() - } else { - vec![] - } + fn get_subnet_hyperparams(netuid: u16) -> Option { + SubtensorModule::get_subnet_hyperparams(netuid) } - fn get_dynamic_info(netuid: u16) -> Vec { - let _result = SubtensorModule::get_dynamic_info(netuid); - if _result.is_some() { - let result = _result.expect("Could not get DynamicInfo."); - result.encode() - } else { - vec![] - } + fn get_dynamic_info(netuid: u16) -> Option> { + SubtensorModule::get_dynamic_info(netuid) } - fn get_metagraph(netuid: u16) -> Vec { - let _result = SubtensorModule::get_metagraph(netuid); - if _result.is_some() { - let result = _result.expect("Could not get Metagraph."); - result.encode() - } else { - vec![] - } + fn get_metagraph(netuid: u16) -> Option> { + SubtensorModule::get_metagraph(netuid) } - fn get_subnet_state(netuid: u16) -> Vec { - let _result = SubtensorModule::get_subnet_state(netuid); - if _result.is_some() { - let result = _result.expect("Could not get SubnetState."); - result.encode() - } else { - vec![] - } + fn get_subnet_state(netuid: u16) -> Option> { + SubtensorModule::get_subnet_state(netuid) } - fn get_all_metagraphs() -> Vec { - let result = SubtensorModule::get_all_metagraphs(); - result.encode() + fn get_all_metagraphs() -> Vec>> { + SubtensorModule::get_all_metagraphs() } - fn get_all_dynamic_info() -> Vec { - let result = SubtensorModule::get_all_dynamic_info(); - result.encode() + fn get_all_dynamic_info() -> Vec>> { + SubtensorModule::get_all_dynamic_info() } } impl subtensor_custom_rpc_runtime_api::StakeInfoRuntimeApi for Runtime { - fn get_stake_info_for_coldkey( coldkey_account_vec: Vec ) -> Vec { - let result = SubtensorModule::get_stake_info_for_coldkey( coldkey_account_vec ); - result.encode() + fn get_stake_info_for_coldkey( coldkey_account: AccountId32 ) -> Vec> { + SubtensorModule::get_stake_info_for_coldkey( coldkey_account ) } - fn get_stake_info_for_coldkeys( coldkey_account_vecs: Vec> ) -> Vec { - let result = SubtensorModule::get_stake_info_for_coldkeys( coldkey_account_vecs ); - result.encode() + fn get_stake_info_for_coldkeys( coldkey_accounts: Vec ) -> Vec<(AccountId32, Vec>)> { + SubtensorModule::get_stake_info_for_coldkeys( coldkey_accounts ) } - fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account_vec: Vec, coldkey_account_vec: Vec, netuid: u16 ) -> Vec { - let result = SubtensorModule::get_stake_info_for_hotkey_coldkey_netuid( hotkey_account_vec, coldkey_account_vec, netuid ); - result.encode() + fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account: AccountId32, coldkey_account: AccountId32, netuid: u16 ) -> Option> { + SubtensorModule::get_stake_info_for_hotkey_coldkey_netuid( hotkey_account, coldkey_account, netuid ) } }