Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RPC API for getting rate limits information #985

Open
wants to merge 2 commits into
base: feat/rao-devnet-ready-2
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion node/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub trait RuntimeApiCollection<
+ subtensor_custom_rpc_runtime_api::NeuronInfoRuntimeApi<Block>
+ subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi<Block>
+ subtensor_custom_rpc_runtime_api::SubnetRegistrationRuntimeApi<Block>
+ subtensor_custom_rpc_runtime_api::RateLimitInfoRuntimeApi<Block>
{
}

Expand All @@ -71,6 +72,7 @@ where
+ subtensor_custom_rpc_runtime_api::DelegateInfoRuntimeApi<Block>
+ subtensor_custom_rpc_runtime_api::NeuronInfoRuntimeApi<Block>
+ subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi<Block>
+ subtensor_custom_rpc_runtime_api::SubnetRegistrationRuntimeApi<Block>,
+ subtensor_custom_rpc_runtime_api::SubnetRegistrationRuntimeApi<Block>
+ subtensor_custom_rpc_runtime_api::RateLimitInfoRuntimeApi<Block>,
{
}
229 changes: 146 additions & 83 deletions pallets/subtensor/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::sync::Arc;
use sp_api::ProvideRuntimeApi;

pub use subtensor_custom_rpc_runtime_api::{
DelegateInfoRuntimeApi, NeuronInfoRuntimeApi, SubnetInfoRuntimeApi,
DelegateInfoRuntimeApi, NeuronInfoRuntimeApi, RateLimitInfoRuntimeApi, SubnetInfoRuntimeApi,
SubnetRegistrationRuntimeApi,
};

Expand Down Expand Up @@ -59,6 +59,22 @@ pub trait SubtensorCustomApi<BlockHash> {
fn get_all_dynamic_info(&self, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;
#[method(name = "subnetInfo_getSubnetState")]
fn get_subnet_state(&self, netuid: u16, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;
#[method(name = "rateLimitInfo_getRateLimits")]
fn get_rate_limits(&self, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;
#[method(name = "rateLimitInfo_getLimitedTxInfoForHotkey")]
fn get_limited_tx_info_for_hotkey(
&self,
hotkey: Vec<u8>,
netuid: u16,
at: Option<BlockHash>,
) -> RpcResult<Vec<u8>>;
#[method(name = "rateLimitInfo_getStakesThisInterval")]
fn get_stakes_this_interval(
&self,
coldkey: Vec<u8>,
hotkey: Vec<u8>,
at: Option<BlockHash>,
) -> RpcResult<u64>;
}

pub struct SubtensorCustom<C, P> {
Expand Down Expand Up @@ -99,6 +115,16 @@ impl From<Error> for i32 {
}
}

macro_rules! call_api {
($self:ident, $at:ident, $err_msg:expr, $name:ident, $($param:ident),* ) => {{
let api = $self.client.runtime_api();
let at = $at.unwrap_or_else(|| $self.client.info().best_hash);

api.$name(at $(,$param)*)
.map_err(|e| Error::RuntimeError(format!("{}: {:?}", $err_msg, e)).into())
}}
}

impl<C, Block> SubtensorCustomApiServer<<Block as BlockT>::Hash> for SubtensorCustom<C, Block>
where
Block: BlockT,
Expand All @@ -107,53 +133,52 @@ where
C::Api: NeuronInfoRuntimeApi<Block>,
C::Api: SubnetInfoRuntimeApi<Block>,
C::Api: SubnetRegistrationRuntimeApi<Block>,
C::Api: RateLimitInfoRuntimeApi<Block>,
{
fn get_delegates(&self, at: Option<<Block as BlockT>::Hash>) -> RpcResult<Vec<u8>> {
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()
})
call_api!(self, at, "Unable to get delegates info", get_delegates,)
}

fn get_delegate(
&self,
delegate_account_vec: Vec<u8>,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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()
})
call_api!(
self,
at,
"Unable to get delegate info",
get_delegate,
delegate_account_vec
)
}

fn get_delegated(
&self,
delegatee_account_vec: Vec<u8>,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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()
})
call_api!(
self,
at,
"Unable to get delegates info",
get_delegated,
delegatee_account_vec
)
}

fn get_neurons_lite(
&self,
netuid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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()
})
call_api!(
self,
at,
"Unable to get neurons lite info",
get_neurons_lite,
netuid
)
}

fn get_neuron_lite(
Expand All @@ -162,20 +187,18 @@ where
uid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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()
})
call_api!(
self,
at,
"Unable to get neuron lite info",
get_neuron_lite,
netuid,
uid
)
}

fn get_neurons(&self, netuid: u16, at: Option<<Block as BlockT>::Hash>) -> RpcResult<Vec<u8>> {
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())
call_api!(self, at, "Unable to get neurons info", get_neurons, netuid)
}

fn get_neuron(
Expand All @@ -184,100 +207,140 @@ where
uid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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())
call_api!(
self,
at,
"Unable to get neuron info",
get_neuron,
netuid,
uid
)
}

fn get_subnet_state(
&self,
netuid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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: {:?}", e)).into())
call_api!(
self,
at,
"Unable to get subnet state",
get_subnet_state,
netuid
)
}

fn get_subnet_info(
&self,
netuid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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())
call_api!(
self,
at,
"Unable to get subnet info",
get_subnet_info,
netuid
)
}

fn get_subnet_hyperparams(
&self,
netuid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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())
call_api!(
self,
at,
"Unable to get subnet hyperparams",
get_subnet_hyperparams,
netuid
)
}

fn get_subnets_info(&self, at: Option<<Block as BlockT>::Hash>) -> RpcResult<Vec<u8>> {
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())
call_api!(self, at, "Unable to get subnets info", get_subnets_info,)
}

fn get_all_dynamic_info(&self, at: Option<<Block as BlockT>::Hash>) -> RpcResult<Vec<u8>> {
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 subnets info: {:?}", e)).into())
call_api!(self, at, "Unable to get subnets info", get_all_dynamic_info,)
}

fn get_dynamic_info(
&self,
netuid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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 subnets info: {:?}", e)).into())
call_api!(
self,
at,
"Unable to get subnets info",
get_dynamic_info,
netuid
)
}

fn get_subnet_info_v2(
&self,
netuid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
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())
call_api!(
self,
at,
"Unable to get subnet info",
get_subnet_info_v2,
netuid
)
}

fn get_subnets_info_v2(&self, at: Option<<Block as BlockT>::Hash>) -> RpcResult<Vec<u8>> {
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())
call_api!(self, at, "Unable to get subnets info", get_subnets_info_v2,)
}

fn get_network_lock_cost(&self, at: Option<<Block as BlockT>::Hash>) -> RpcResult<u64> {
let api = self.client.runtime_api();
let at = at.unwrap_or_else(|| self.client.info().best_hash);
call_api!(
self,
at,
"Unable to get subnet lock cost",
get_network_registration_cost,
)
}

fn get_rate_limits(&self, at: Option<<Block as BlockT>::Hash>) -> RpcResult<Vec<u8>> {
call_api!(self, at, "Unable to get rate limits", get_rate_limits,)
}

api.get_network_registration_cost(at).map_err(|e| {
Error::RuntimeError(format!("Unable to get subnet lock cost: {:?}", e)).into()
})
fn get_limited_tx_info_for_hotkey(
&self,
hotkey: Vec<u8>,
netuid: u16,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<Vec<u8>> {
call_api!(
self,
at,
"Unable to get rate limits info for hotkey",
get_limited_tx_info_for_hotkey,
hotkey,
netuid
)
}

fn get_stakes_this_interval(
&self,
coldkey: Vec<u8>,
hotkey: Vec<u8>,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<u64> {
call_api!(
self,
at,
"Unable to get number of stakes for the interval",
get_stakes_this_interval,
coldkey,
hotkey
)
}
}
14 changes: 12 additions & 2 deletions pallets/subtensor/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,21 @@ sp_api::decl_runtime_apis! {
}

pub trait StakeInfoRuntimeApi {
fn get_stake_info_for_coldkey( coldkey_account_vec: Vec<u8> ) -> Vec<u8>;
fn get_stake_info_for_coldkeys( coldkey_account_vecs: Vec<Vec<u8>> ) -> Vec<u8>;
fn get_stake_info_for_coldkey(coldkey_account_vec: Vec<u8>) -> Vec<u8>;
fn get_stake_info_for_coldkeys(coldkey_account_vecs: Vec<Vec<u8>>) -> Vec<u8>;
}

pub trait SubnetRegistrationRuntimeApi {
fn get_network_registration_cost() -> u64;
}

/// API for getting transaction rate limits associated with coldkeys and hotkeys.
pub trait RateLimitInfoRuntimeApi {
/// Get transactions rate limits.
fn get_rate_limits() -> Vec<u8>;
/// Get transaction rate limits associated with the `hotkey`.
fn get_limited_tx_info_for_hotkey(hotkey: Vec<u8>, netuid: u16) -> Vec<u8>;
/// Get number of stakes associated with coldkey/hotkey pair, made during `StakeInterval`.
fn get_stakes_this_interval(coldkey: Vec<u8>, hotkey: Vec<u8>) -> u64;
}
}
1 change: 1 addition & 0 deletions pallets/subtensor/src/rpc_info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::*;
pub mod delegate_info;
pub mod dynamic_info;
pub mod neuron_info;
pub mod rate_limit_info;
pub mod show_subnet;
pub mod stake_info;
pub mod subnet_info;
Loading
Loading