Skip to content

Commit

Permalink
feat: implement subnetinfov2 , add_network with identities
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Dare committed Aug 26, 2024
1 parent 8c17cfd commit 41b6ae6
Show file tree
Hide file tree
Showing 10 changed files with 271 additions and 45 deletions.
2 changes: 1 addition & 1 deletion pallets/admin-utils/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ fn test_sudo_get_set_alpha() {
DispatchError::BadOrigin
);

assert_ok!(SubtensorModule::register_network(signer.clone(), None));
assert_ok!(SubtensorModule::register_network(signer.clone()));

assert_ok!(AdminUtils::sudo_set_alpha_values(
signer.clone(),
Expand Down
24 changes: 24 additions & 0 deletions pallets/subtensor/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ pub trait SubtensorCustomApi<BlockHash> {
fn get_subnet_info(&self, netuid: u16, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;
#[method(name = "subnetInfo_getSubnetsInfo")]
fn get_subnets_info(&self, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;
#[method(name = "subnetInfo_getSubnetInfo_v2")]
fn get_subnet_info_v2(&self, netuid: u16, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;
#[method(name = "subnetInfo_getSubnetsInf_v2")]
fn get_subnets_info_v2(&self, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;
#[method(name = "subnetInfo_getSubnetHyperparams")]
fn get_subnet_hyperparams(&self, netuid: u16, at: Option<BlockHash>) -> RpcResult<Vec<u8>>;

Expand Down Expand Up @@ -215,6 +219,26 @@ where
.map_err(|e| Error::RuntimeError(format!("Unable to get subnets info: {:?}", e)).into())
}

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())
}

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())
}

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);
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ sp_api::decl_runtime_apis! {
pub trait SubnetInfoRuntimeApi {
fn get_subnet_info(netuid: u16) -> Vec<u8>;
fn get_subnets_info() -> Vec<u8>;
fn get_subnet_info_v2(netuid: u16) -> Vec<u8>;
fn get_subnets_info_v2() -> Vec<u8>;
fn get_subnet_hyperparams(netuid: u16) -> Vec<u8>;
}

Expand Down
125 changes: 115 additions & 10 deletions pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,100 @@ impl<T: Config> Pallet<T> {
///
/// # Args:
/// * `origin` (`T::RuntimeOrigin`): The calling origin. Must be signed.
///
/// # Events:
/// * `NetworkAdded(netuid, modality)`: Emitted when a new network is successfully added.
/// * `NetworkRemoved(netuid)`: Emitted when an existing network is removed to make room for the new one.
///
/// # Raises:
/// * 'TxRateLimitExceeded': If the rate limit for network registration is exceeded.
/// * 'NotEnoughBalanceToStake': If there isn't enough balance to stake for network registration.
/// * 'BalanceWithdrawalError': If an error occurs during balance withdrawal for network registration.
///
pub fn user_add_network(origin: T::RuntimeOrigin) -> dispatch::DispatchResult {
// --- 0. Ensure the caller is a signed user.
let coldkey = ensure_signed(origin)?;

// --- 1. Rate limit for network registrations.
let current_block = Self::get_current_block_as_u64();
let last_lock_block = Self::get_network_last_lock_block();
ensure!(
current_block.saturating_sub(last_lock_block) >= NetworkRateLimit::<T>::get(),
Error::<T>::NetworkTxRateLimitExceeded
);

// --- 2. Calculate and lock the required tokens.
let lock_amount: u64 = Self::get_network_lock_cost();
log::debug!("network lock_amount: {:?}", lock_amount);
ensure!(
Self::can_remove_balance_from_coldkey_account(&coldkey, lock_amount),
Error::<T>::NotEnoughBalanceToStake
);

// --- 4. Determine the netuid to register.
let netuid_to_register: u16 = {
log::debug!(
"subnet count: {:?}\nmax subnets: {:?}",
Self::get_num_subnets(),
Self::get_max_subnets()
);
if Self::get_num_subnets().saturating_sub(1) < Self::get_max_subnets() {
// We subtract one because we don't want root subnet to count towards total
let mut next_available_netuid = 0;
loop {
next_available_netuid.saturating_inc();
if !Self::if_subnet_exist(next_available_netuid) {
log::debug!("got subnet id: {:?}", next_available_netuid);
break next_available_netuid;
}
}
} else {
let netuid_to_prune = Self::get_subnet_to_prune();
ensure!(netuid_to_prune > 0, Error::<T>::AllNetworksInImmunity);

Self::remove_network(netuid_to_prune);
log::debug!("remove_network: {:?}", netuid_to_prune,);
Self::deposit_event(Event::NetworkRemoved(netuid_to_prune));

if SubnetIdentities::<T>::take(netuid_to_prune).is_some() {
Self::deposit_event(Event::SubnetIdentityRemoved(netuid_to_prune));
}

netuid_to_prune
}
};

// --- 5. Perform the lock operation.
let actual_lock_amount = Self::remove_balance_from_coldkey_account(&coldkey, lock_amount)?;
Self::set_subnet_locked_balance(netuid_to_register, actual_lock_amount);
Self::set_network_last_lock(actual_lock_amount);

// --- 6. Set initial and custom parameters for the network.
Self::init_new_network(netuid_to_register, 360);
log::debug!("init_new_network: {:?}", netuid_to_register,);

// --- 7. Set netuid storage.
let current_block_number: u64 = Self::get_current_block_as_u64();
NetworkLastRegistered::<T>::set(current_block_number);
NetworkRegisteredAt::<T>::insert(netuid_to_register, current_block_number);
SubnetOwner::<T>::insert(netuid_to_register, coldkey);

// --- 8. Emit the NetworkAdded event.
log::debug!(
"NetworkAdded( netuid:{:?}, modality:{:?} )",
netuid_to_register,
0
);
Self::deposit_event(Event::NetworkAdded(netuid_to_register, 0));

// --- 9. Return success.
Ok(())
}

/// Facilitates user registration of a new subnetwork with subnet identity.
///
/// # Args:
/// * `origin` (`T::RuntimeOrigin`): The calling origin. Must be signed.
/// * `identity` (`Option<SubnetIdentityOf>`): Optional identity to be associated with the new subnetwork.
///
/// # Events:
Expand All @@ -908,7 +1002,7 @@ impl<T: Config> Pallet<T> {
/// * 'NotEnoughBalanceToStake': If there isn't enough balance to stake for network registration.
/// * 'BalanceWithdrawalError': If an error occurs during balance withdrawal for network registration.
///
pub fn user_add_network(
pub fn user_add_network_with_identity(
origin: T::RuntimeOrigin,
identity: Option<SubnetIdentityOf>,
) -> dispatch::DispatchResult {
Expand Down Expand Up @@ -1126,8 +1220,8 @@ impl<T: Config> Pallet<T> {
/// Removes a network (identified by netuid) and all associated parameters.
///
/// This function is responsible for cleaning up all the data associated with a network.
/// It ensures that all the storage values related to the network are removed, and any
/// reserved balance is returned to the network owner.
/// It ensures that all the storage values related to the network are removed, any
/// reserved balance is returned to the network owner, and the subnet identity is removed if it exists.
///
/// # Args:
/// * 'netuid': ('u16'): The unique identifier of the network to be removed.
Expand All @@ -1136,10 +1230,15 @@ impl<T: Config> Pallet<T> {
/// This function does not emit any events, nor does it raise any errors. It silently
/// returns if any internal checks fail.
///
/// # Example:
/// ```rust
/// let netuid_to_remove: u16 = 5;
/// Pallet::<T>::remove_network(netuid_to_remove);
/// ```
pub fn remove_network(netuid: u16) {
// --- 1. Return balance to subnet owner.
let owner_coldkey = SubnetOwner::<T>::get(netuid);
let reserved_amount = Self::get_subnet_locked_balance(netuid);
let owner_coldkey: T::AccountId = SubnetOwner::<T>::get(netuid);
let reserved_amount: u64 = Self::get_subnet_locked_balance(netuid);

// --- 2. Remove network count.
SubnetworkN::<T>::remove(netuid);
Expand All @@ -1150,13 +1249,13 @@ impl<T: Config> Pallet<T> {
// --- 4. Remove netuid from added networks.
NetworksAdded::<T>::remove(netuid);

// --- 6. Decrement the network counter.
TotalNetworks::<T>::mutate(|n| *n = n.saturating_sub(1));
// --- 5. Decrement the network counter.
TotalNetworks::<T>::mutate(|n: &mut u16| *n = n.saturating_sub(1));

// --- 7. Remove various network-related storages.
// --- 6. Remove various network-related storages.
NetworkRegisteredAt::<T>::remove(netuid);

// --- 8. Remove incentive mechanism memory.
// --- 7. Remove incentive mechanism memory.
let _ = Uids::<T>::clear_prefix(netuid, u32::MAX, None);
let _ = Keys::<T>::clear_prefix(netuid, u32::MAX, None);
let _ = Bonds::<T>::clear_prefix(netuid, u32::MAX, None);
Expand All @@ -1171,7 +1270,7 @@ impl<T: Config> Pallet<T> {
)
{
// Create a new vector to hold modified weights.
let mut modified_weights = weights_i.clone();
let mut modified_weights: Vec<(u16, u16)> = weights_i.clone();
// Iterate over each weight entry to potentially update it.
for (subnet_id, weight) in modified_weights.iter_mut() {
if subnet_id == &netuid {
Expand Down Expand Up @@ -1213,6 +1312,12 @@ impl<T: Config> Pallet<T> {
Self::add_balance_to_coldkey_account(&owner_coldkey, reserved_amount);
Self::set_subnet_locked_balance(netuid, 0);
SubnetOwner::<T>::remove(netuid);

// --- 13. Remove subnet identity if it exists.
if SubnetIdentities::<T>::contains_key(netuid) {
SubnetIdentities::<T>::remove(netuid);
Self::deposit_event(Event::SubnetIdentityRemoved(netuid));
}
}

#[allow(clippy::arithmetic_side_effects)]
Expand Down
19 changes: 14 additions & 5 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -901,11 +901,8 @@ mod dispatches {
#[pallet::weight((Weight::from_parts(157_000_000, 0)
.saturating_add(T::DbWeight::get().reads(16))
.saturating_add(T::DbWeight::get().writes(30)), DispatchClass::Operational, Pays::No))]
pub fn register_network(
origin: OriginFor<T>,
identity: Option<SubnetIdentityOf>,
) -> DispatchResult {
Self::user_add_network(origin, identity)
pub fn register_network(origin: OriginFor<T>) -> DispatchResult {
Self::user_add_network(origin)
}

/// Facility extrinsic for user to get taken from faucet
Expand Down Expand Up @@ -1201,5 +1198,17 @@ mod dispatches {
) -> DispatchResult {
Self::do_set_subnet_identity(origin, netuid, subnet_name, github_repo, subnet_contact)
}

/// User register a new subnetwork
#[pallet::call_index(79)]
#[pallet::weight((Weight::from_parts(157_000_000, 0)
.saturating_add(T::DbWeight::get().reads(16))
.saturating_add(T::DbWeight::get().writes(30)), DispatchClass::Operational, Pays::No))]
pub fn register_network_with_identity(
origin: OriginFor<T>,
identity: Option<SubnetIdentityOf>,
) -> DispatchResult {
Self::user_add_network_with_identity(origin, identity)
}
}
}
Loading

0 comments on commit 41b6ae6

Please sign in to comment.