Skip to content

Commit

Permalink
feat: coldkey swap info
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Dare committed Jul 9, 2024
1 parent 4eefcf9 commit e30c8f4
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 62 deletions.
1 change: 1 addition & 0 deletions node/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ where
C::Api: subtensor_custom_rpc_runtime_api::NeuronInfoRuntimeApi<Block>,
C::Api: subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi<Block>,
C::Api: subtensor_custom_rpc_runtime_api::SubnetRegistrationRuntimeApi<Block>,
C::Api: subtensor_custom_rpc_runtime_api::ColdkeySwapRuntimeApi<Block>,
B: sc_client_api::Backend<Block> + Send + Sync + 'static,
P: TransactionPool + 'static,
{
Expand Down
68 changes: 67 additions & 1 deletion 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,
ColdkeySwapRuntimeApi, DelegateInfoRuntimeApi, NeuronInfoRuntimeApi, SubnetInfoRuntimeApi,
SubnetRegistrationRuntimeApi,
};

Expand Down Expand Up @@ -51,6 +51,24 @@ pub trait SubtensorCustomApi<BlockHash> {

#[method(name = "subnetInfo_getLockCost")]
fn get_network_lock_cost(&self, at: Option<BlockHash>) -> RpcResult<u64>;
#[method(name = "coldkeySwap_getScheduledColdkeySwap")]
fn get_scheduled_coldkey_swap(
&self,
coldkey_account_vec: Vec<u8>,
at: Option<BlockHash>,
) -> RpcResult<Vec<u8>>;
#[method(name = "coldkeySwap_getRemainingArbitrationPeriod")]
fn get_remaining_arbitration_period(
&self,
coldkey_account_vec: Vec<u8>,
at: Option<BlockHash>,
) -> RpcResult<Vec<u8>>;
#[method(name = "coldkeySwap_getColdkeySwapDestinations")]
fn get_coldkey_swap_destinations(
&self,
coldkey_account_vec: Vec<u8>,
at: Option<BlockHash>,
) -> RpcResult<Vec<u8>>;
}

pub struct SubtensorCustom<C, P> {
Expand Down Expand Up @@ -99,6 +117,7 @@ where
C::Api: NeuronInfoRuntimeApi<Block>,
C::Api: SubnetInfoRuntimeApi<Block>,
C::Api: SubnetRegistrationRuntimeApi<Block>,
C::Api: ColdkeySwapRuntimeApi<Block>,
{
fn get_delegates(&self, at: Option<<Block as BlockT>::Hash>) -> RpcResult<Vec<u8>> {
let api = self.client.runtime_api();
Expand Down Expand Up @@ -223,4 +242,51 @@ where
Error::RuntimeError(format!("Unable to get subnet lock cost: {:?}", e)).into()
})
}

fn get_scheduled_coldkey_swap(
&self,
coldkey_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_scheduled_coldkey_swap(at, coldkey_account_vec)
.map_err(|e| {
Error::RuntimeError(format!("Unable to get scheduled coldkey swap: {:?}", e)).into()
})
}

fn get_remaining_arbitration_period(
&self,
coldkey_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_remaining_arbitration_period(at, coldkey_account_vec)
.map_err(|e| {
Error::RuntimeError(format!(
"Unable to get remaining arbitration period: {:?}",
e
))
.into()
})
}

fn get_coldkey_swap_destinations(
&self,
coldkey_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_coldkey_swap_destinations(at, coldkey_account_vec)
.map_err(|e| {
Error::RuntimeError(format!("Unable to get coldkey swap destinations: {:?}", e))
.into()
})
}
}
6 changes: 6 additions & 0 deletions pallets/subtensor/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ sp_api::decl_runtime_apis! {
pub trait SubnetRegistrationRuntimeApi {
fn get_network_registration_cost() -> u64;
}

pub trait ColdkeySwapRuntimeApi {
fn get_scheduled_coldkey_swap( coldkey_account_vec: Vec<u8> ) -> Vec<u8>;
fn get_remaining_arbitration_period( coldkey_account_vec: Vec<u8> ) -> Vec<u8>;
fn get_coldkey_swap_destinations( coldkey_account_vec: Vec<u8> ) -> Vec<u8>;
}
}
1 change: 1 addition & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ mod weights;

pub mod delegate_info;
pub mod neuron_info;
pub mod schedule_coldkey_swap_info;
pub mod stake_info;
pub mod subnet_info;

Expand Down
172 changes: 172 additions & 0 deletions pallets/subtensor/src/schedule_coldkey_swap_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
use super::*;
use codec::Compact;
use frame_support::pallet_prelude::{Decode, Encode};
use sp_core::hexdisplay::AsBytesRef;

#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)]
pub struct ScheduledColdkeySwapInfo<T: Config> {
old_coldkey: T::AccountId,
new_coldkey: T::AccountId,
arbitration_block: Compact<u64>,
}

impl<T: Config> Pallet<T> {
/// Retrieves the scheduled coldkey swap information for an existing account.
///
/// # Arguments
///
/// * `coldkey` - The account ID of the coldkey to check.
///
/// # Returns
///
/// * `Option<ScheduledColdkeySwapInfo<T>>` - The scheduled coldkey swap information if it exists, otherwise `None`.
///
/// # Notes
///
/// This function checks if there are any destination coldkeys associated with the given coldkey.
/// If there are, it retrieves the arbitration block and constructs the `ScheduledColdkeySwapInfo` struct.
fn get_scheduled_coldkey_swap_by_existing_account(
coldkey: AccountIdOf<T>,
) -> Option<ScheduledColdkeySwapInfo<T>> {
let destinations: Vec<T::AccountId> = ColdkeySwapDestinations::<T>::get(&coldkey);
if destinations.is_empty() {
return None;
}

let arbitration_block: u64 = ColdkeyArbitrationBlock::<T>::get(&coldkey);

Some(ScheduledColdkeySwapInfo {
old_coldkey: coldkey,
new_coldkey: destinations[0].clone(),
arbitration_block: arbitration_block.into(),
})
}

/// Retrieves the scheduled coldkey swap information for a given coldkey account vector.
///
/// # Arguments
///
/// * `coldkey_account_vec` - The vector of bytes representing the coldkey account.
///
/// # Returns
///
/// * `Option<ScheduledColdkeySwapInfo<T>>` - The scheduled coldkey swap information if it exists, otherwise `None`.
///
/// # Notes
///
/// This function decodes the coldkey account vector into an account ID and then calls
/// `get_scheduled_coldkey_swap_by_existing_account` to retrieve the swap information.
pub fn get_scheduled_coldkey_swap(
coldkey_account_vec: Vec<u8>,
) -> Option<ScheduledColdkeySwapInfo<T>> {
if coldkey_account_vec.len() != 32 {
return None;
}

let coldkey: AccountIdOf<T> =
T::AccountId::decode(&mut coldkey_account_vec.as_bytes_ref()).ok()?;
Self::get_scheduled_coldkey_swap_by_existing_account(coldkey)
}

/// Retrieves all scheduled coldkey swaps from storage.
///
/// # Returns
///
/// * `Vec<ScheduledColdkeySwapInfo<T>>` - A vector containing all scheduled coldkey swap information.
///
/// # Notes
///
/// This function iterates over all coldkeys in `ColdkeySwapDestinations` and retrieves their swap information
/// using `get_scheduled_coldkey_swap_by_existing_account`.
pub fn get_all_scheduled_coldkey_swaps() -> Vec<ScheduledColdkeySwapInfo<T>> {
let mut scheduled_swaps: Vec<ScheduledColdkeySwapInfo<T>> = Vec::new();
for coldkey in ColdkeySwapDestinations::<T>::iter_keys() {
if let Some(swap_info) = Self::get_scheduled_coldkey_swap_by_existing_account(coldkey) {
scheduled_swaps.push(swap_info);
}
}
scheduled_swaps
}

/// Retrieves the scheduled coldkey swaps for a given block.
///
/// # Arguments
///
/// * `block` - The block number to check for scheduled coldkey swaps.
///
/// # Returns
///
/// * `Vec<ScheduledColdkeySwapInfo<T>>` - A vector containing the scheduled coldkey swap information for the given block.
///
/// # Notes
///
/// This function retrieves the coldkeys to swap at the given block and then retrieves their swap information
/// using `get_scheduled_coldkey_swap_by_existing_account`.
pub fn get_scheduled_coldkey_swaps_at_block(block: u64) -> Vec<ScheduledColdkeySwapInfo<T>> {
let coldkeys_to_swap: Vec<T::AccountId> = ColdkeysToSwapAtBlock::<T>::get(block);
let mut scheduled_swaps: Vec<ScheduledColdkeySwapInfo<T>> = Vec::new();
for coldkey in coldkeys_to_swap {
if let Some(swap_info) = Self::get_scheduled_coldkey_swap_by_existing_account(coldkey) {
scheduled_swaps.push(swap_info);
}
}
scheduled_swaps
}

/// Retrieves the remaining arbitration period for a given coldkey account vector.
///
/// # Arguments
///
/// * `coldkey_account_vec` - The vector of bytes representing the coldkey account.
///
/// # Returns
///
/// * `Option<u64>` - The remaining arbitration period in blocks if it exists, otherwise `None`.
///
/// # Notes
///
/// This function decodes the coldkey account vector into an account ID and calculates the remaining arbitration period
/// by subtracting the current block number from the arbitration block number.
pub fn get_remaining_arbitration_period(coldkey_account_vec: Vec<u8>) -> Option<u64> {
if coldkey_account_vec.len() != 32 {
return None;
}

let coldkey: AccountIdOf<T> =
T::AccountId::decode(&mut coldkey_account_vec.as_bytes_ref()).ok()?;
let current_block: u64 = Self::get_current_block_as_u64();
let arbitration_block: u64 = ColdkeyArbitrationBlock::<T>::get(&coldkey);

if arbitration_block > current_block {
Some(arbitration_block.saturating_sub(current_block))
} else {
Some(0)
}
}

/// Retrieves the destination coldkeys for a given coldkey account vector.
///
/// # Arguments
///
/// * `coldkey_account_vec` - The vector of bytes representing the coldkey account.
///
/// # Returns
///
/// * `Option<Vec<T::AccountId>>` - A vector containing the destination coldkeys if they exist, otherwise `None`.
///
/// # Notes
///
/// This function decodes the coldkey account vector into an account ID and retrieves the destination coldkeys
/// from `ColdkeySwapDestinations`.
pub fn get_coldkey_swap_destinations(
coldkey_account_vec: Vec<u8>,
) -> Option<Vec<T::AccountId>> {
if coldkey_account_vec.len() != 32 {
return None;
}

let coldkey: AccountIdOf<T> =
T::AccountId::decode(&mut coldkey_account_vec.as_bytes_ref()).ok()?;
Some(ColdkeySwapDestinations::<T>::get(&coldkey))
}
}
18 changes: 9 additions & 9 deletions pallets/subtensor/src/swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,15 @@ impl<T: Config> Pallet<T> {
///
/// This function calculates the remaining arbitration period by subtracting the current block number
/// from the arbitration block number of the coldkey.
pub fn get_remaining_arbitration_period(coldkey: &T::AccountId) -> u64 {
let current_block: u64 = Self::get_current_block_as_u64();
let arbitration_block: u64 = ColdkeyArbitrationBlock::<T>::get(coldkey);
if arbitration_block > current_block {
arbitration_block.saturating_sub(current_block)
} else {
0
}
}
// pub fn get_remaining_arbitration_period(coldkey: &T::AccountId) -> u64 {
// let current_block: u64 = Self::get_current_block_as_u64();
// let arbitration_block: u64 = ColdkeyArbitrationBlock::<T>::get(coldkey);
// if arbitration_block > current_block {
// arbitration_block.saturating_sub(current_block)
// } else {
// 0
// }
// }

pub fn meets_min_allowed_coldkey_balance(coldkey: &T::AccountId) -> bool {
let all_staked_keys: Vec<T::AccountId> = StakingHotkeys::<T>::get(coldkey);
Expand Down
Loading

0 comments on commit e30c8f4

Please sign in to comment.