Skip to content
Merged
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
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>>;
Comment on lines +49 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do all our custom rpc return bytes? It makes them annoying to consume, and returning a SCALE encoded type is no less efficient.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would you rather they returned ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah 100% agree on this, opens us up to all sorts of potential footguns and even vulnerabilities potentially on the input side if certain criteria are met

Copy link
Contributor

@orriin orriin Aug 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would you rather they returned ?

The actual shape of the data. SubnetInfov2/Vec<SubnetInfov2>/Result<Vec<Option<SubnetInfov2>>>, or whatever it is before you call .encode

#[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
8 changes: 4 additions & 4 deletions pallets/subtensor/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ benchmarks! {
let amount: u64 = 1;
let amount_to_be_staked = 100_000_000_000_000u64;
Subtensor::<T>::add_balance_to_coldkey_account(&coldkey.clone(), amount_to_be_staked);
}: register_network(RawOrigin::Signed(coldkey), None)
}: register_network(RawOrigin::Signed(coldkey))

benchmark_dissolve_network {
let seed : u32 = 1;
Expand All @@ -311,8 +311,8 @@ benchmarks! {
let amount: u64 = 1;
let amount_to_be_staked = 100_000_000_000_000u64;
Subtensor::<T>::add_balance_to_coldkey_account(&coldkey.clone(), amount_to_be_staked);
assert_ok!(Subtensor::<T>::register_network(RawOrigin::Signed(coldkey.clone()).into(), None));
}: dissolve_network(RawOrigin::Signed(coldkey), 1)
assert_ok!(Subtensor::<T>::register_network(RawOrigin::Signed(coldkey.clone()).into()));
}: dissolve_network(RawOrigin::Root, coldkey.clone(), 1)


// swap_hotkey {
Expand Down Expand Up @@ -519,6 +519,6 @@ reveal_weights {
Identities::<T>::insert(&old_coldkey, identity);

// Benchmark setup complete, now execute the extrinsic
}: swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), old_coldkey.clone(), new_coldkey.clone())
}: swap_coldkey(RawOrigin::Root, old_coldkey.clone(), new_coldkey.clone())

}
27 changes: 16 additions & 11 deletions pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ impl<T: Config> Pallet<T> {
.into())
}

/// Facilitates user registration of a new subnetwork.
/// Facilitates user registration of a new subnetwork with subnet identity.
///
/// # Args:
/// * `origin` (`T::RuntimeOrigin`): The calling origin. Must be signed.
Expand Down Expand Up @@ -1126,20 +1126,19 @@ 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.
///
/// # Note:
/// This function does not emit any events, nor does it raise any errors. It silently
/// returns if any internal checks fail.
///
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 +1149,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 +1170,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 +1212,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, None)
}

/// 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(origin, identity)
}
}
}
99 changes: 95 additions & 4 deletions pallets/subtensor/src/rpc_info/subnet_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use frame_support::storage::IterableStorageMap;
extern crate alloc;
use codec::Compact;

#[freeze_struct("ccca539640c3f631")]
#[freeze_struct("fe79d58173da662a")]
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)]
pub struct SubnetInfo<T: Config> {
netuid: Compact<u16>,
Expand All @@ -25,6 +25,29 @@ pub struct SubnetInfo<T: Config> {
emission_values: Compact<u64>,
burn: Compact<u64>,
owner: T::AccountId,
}

#[freeze_struct("65f931972fa13222")]
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)]
pub struct SubnetInfov2<T: Config> {
netuid: Compact<u16>,
rho: Compact<u16>,
kappa: Compact<u16>,
difficulty: Compact<u64>,
immunity_period: Compact<u16>,
max_allowed_validators: Compact<u16>,
min_allowed_weights: Compact<u16>,
max_weights_limit: Compact<u16>,
scaling_law_power: Compact<u16>,
subnetwork_n: Compact<u16>,
max_allowed_uids: Compact<u16>,
blocks_since_last_step: Compact<u64>,
tempo: Compact<u16>,
network_modality: Compact<u16>,
network_connect: Vec<[u16; 2]>,
emission_values: Compact<u64>,
burn: Compact<u64>,
owner: T::AccountId,
identity: Option<SubnetIdentity>,
}

Expand Down Expand Up @@ -81,8 +104,6 @@ impl<T: Config> Pallet<T> {
let network_modality = <NetworkModality<T>>::get(netuid);
let emission_values = Self::get_emission_value(netuid);
let burn: Compact<u64> = Self::get_burn_as_u64(netuid).into();
let identity: Option<SubnetIdentity> = SubnetIdentities::<T>::get(netuid);

// DEPRECATED
let network_connect: Vec<[u16; 2]> = Vec::<[u16; 2]>::new();
// DEPRECATED for ( _netuid_, con_req) in < NetworkConnect<T> as IterableStorageDoubleMap<u16, u16, u16> >::iter_prefix(netuid) {
Expand All @@ -108,7 +129,6 @@ impl<T: Config> Pallet<T> {
emission_values: emission_values.into(),
burn,
owner: Self::get_subnet_owner(netuid),
identity,
})
}

Expand All @@ -134,6 +154,77 @@ impl<T: Config> Pallet<T> {
subnets_info
}

pub fn get_subnet_info_v2(netuid: u16) -> Option<SubnetInfov2<T>> {
if !Self::if_subnet_exist(netuid) {
return None;
}

let rho = Self::get_rho(netuid);
let kappa = Self::get_kappa(netuid);
let difficulty: Compact<u64> = Self::get_difficulty_as_u64(netuid).into();
let immunity_period = Self::get_immunity_period(netuid);
let max_allowed_validators = Self::get_max_allowed_validators(netuid);
let min_allowed_weights = Self::get_min_allowed_weights(netuid);
let max_weights_limit = Self::get_max_weight_limit(netuid);
let scaling_law_power = Self::get_scaling_law_power(netuid);
let subnetwork_n = Self::get_subnetwork_n(netuid);
let max_allowed_uids = Self::get_max_allowed_uids(netuid);
let blocks_since_last_step = Self::get_blocks_since_last_step(netuid);
let tempo = Self::get_tempo(netuid);
let network_modality = <NetworkModality<T>>::get(netuid);
let emission_values = Self::get_emission_value(netuid);
let burn: Compact<u64> = Self::get_burn_as_u64(netuid).into();
let identity: Option<SubnetIdentity> = SubnetIdentities::<T>::get(netuid);

// DEPRECATED
let network_connect: Vec<[u16; 2]> = Vec::<[u16; 2]>::new();
// DEPRECATED for ( _netuid_, con_req) in < NetworkConnect<T> as IterableStorageDoubleMap<u16, u16, u16> >::iter_prefix(netuid) {
// network_connect.push([_netuid_, con_req]);
// }

Some(SubnetInfov2 {
rho: rho.into(),
kappa: kappa.into(),
difficulty,
immunity_period: immunity_period.into(),
netuid: netuid.into(),
max_allowed_validators: max_allowed_validators.into(),
min_allowed_weights: min_allowed_weights.into(),
max_weights_limit: max_weights_limit.into(),
scaling_law_power: scaling_law_power.into(),
subnetwork_n: subnetwork_n.into(),
max_allowed_uids: max_allowed_uids.into(),
blocks_since_last_step: blocks_since_last_step.into(),
tempo: tempo.into(),
network_modality: network_modality.into(),
network_connect,
emission_values: emission_values.into(),
burn,
owner: Self::get_subnet_owner(netuid),
identity,
})
}
pub fn get_subnets_info_v2() -> Vec<Option<SubnetInfo<T>>> {
let mut subnet_netuids = Vec::<u16>::new();
let mut max_netuid: u16 = 0;
for (netuid, added) in <NetworksAdded<T> as IterableStorageMap<u16, bool>>::iter() {
if added {
subnet_netuids.push(netuid);
if netuid > max_netuid {
max_netuid = netuid;
}
}
}

let mut subnets_info = Vec::<Option<SubnetInfo<T>>>::new();
for netuid_ in 0..=max_netuid {
if subnet_netuids.contains(&netuid_) {
subnets_info.push(Self::get_subnet_info(netuid_));
}
}

subnets_info
}
pub fn get_subnet_hyperparams(netuid: u16) -> Option<SubnetHyperparams> {
if !Self::if_subnet_exist(netuid) {
return None;
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/tests/epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,7 @@ fn test_set_alpha_disabled() {
assert_ok!(SubtensorModule::root_register(signer.clone(), hotkey,));
assert_ok!(SubtensorModule::add_stake(signer.clone(), hotkey, 1000));
// Only owner can set alpha values
assert_ok!(SubtensorModule::register_network(signer.clone(), None));
assert_ok!(SubtensorModule::register_network(signer.clone()));

// Explicitly set to false
SubtensorModule::set_liquid_alpha_enabled(netuid, false);
Expand Down Expand Up @@ -2584,7 +2584,7 @@ fn test_get_set_alpha() {
DispatchError::BadOrigin
);

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

assert_ok!(SubtensorModule::do_set_alpha_values(
signer.clone(),
Expand Down
1 change: 0 additions & 1 deletion pallets/subtensor/tests/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ fn test_total_issuance_global() {
assert_eq!(SubtensorModule::get_total_issuance(), 0); // initial is zero.
assert_ok!(SubtensorModule::register_network(
<<Test as Config>::RuntimeOrigin>::signed(owner),
None
));
SubtensorModule::set_max_allowed_uids(netuid, 1); // Set the maximum allowed unique identifiers for the network to 1.
assert_eq!(SubtensorModule::get_total_issuance(), 0); // initial is zero.
Expand Down
Loading