Skip to content

Commit

Permalink
feat: revoke multiple children + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Dare committed Jun 23, 2024
1 parent 26908c3 commit b33f55a
Show file tree
Hide file tree
Showing 4 changed files with 418 additions and 0 deletions.
90 changes: 90 additions & 0 deletions pallets/subtensor/src/children.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,96 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Revokes multiple children for a given hotkey on a specified network.
///
/// This function allows a coldkey to revoke multiple children for a given hotkey on a specified network.
///
/// # Arguments:
/// * `origin` (<T as frame_system::Config>::RuntimeOrigin):
/// - The signature of the calling coldkey. Revoking hotkey children can only be done by the coldkey.
///
/// * `hotkey` (T::AccountId):
/// - The hotkey from which the children will be revoked.
///
/// * `children` (Vec<T::AccountId>):
/// - A vector of AccountIds representing the children to be revoked.
///
/// * `netuid` (u16):
/// - The u16 network identifier where the childkeys exist.
///
/// # Events:
/// * `ChildrenRevokedMultiple`:
/// - On successfully revoking multiple children from a hotkey.
///
/// # Errors:
/// * `SubNetworkDoesNotExist`:
/// - Attempting to revoke from a non-existent network.
/// * `NonAssociatedColdKey`:
/// - The coldkey does not own the hotkey.
/// * `HotKeyAccountNotExists`:
/// - The hotkey account does not exist.
pub fn do_revoke_children_multiple(
origin: T::RuntimeOrigin,
hotkey: T::AccountId,
children: Vec<T::AccountId>,
netuid: u16,
) -> DispatchResult {
// --- 1. Check that the caller has signed the transaction. (the coldkey of the pairing)
let coldkey = ensure_signed(origin)?;
log::info!(
"do_revoke_children_multiple( coldkey:{:?} netuid:{:?} hotkey:{:?} children:{:?} )",
coldkey,
netuid,
hotkey,
children
);

// --- 2. Check that the network we are trying to revoke the children from exists.
ensure!(
Self::if_subnet_exist(netuid),
Error::<T>::SubNetworkDoesNotExist
);

// --- 3. Check that the coldkey owns the hotkey.
ensure!(
Self::coldkey_owns_hotkey(&coldkey, &hotkey),
Error::<T>::NonAssociatedColdKey
);

// --- 4. Get the current children of the hotkey.
let mut current_children: Vec<(u64, T::AccountId)> =
ChildKeys::<T>::get(hotkey.clone(), netuid);

// --- 5. Remove the specified children from the hotkey's children list.
current_children.retain(|(_, child)| !children.contains(child));

// --- 6. Update the children list in storage.
ChildKeys::<T>::insert(hotkey.clone(), netuid, current_children);

// --- 7. Remove the hotkey from each child's parent list.
for child in children.iter() {
let mut parents: Vec<(u64, T::AccountId)> = ParentKeys::<T>::get(child.clone(), netuid);
parents.retain(|(_, p)| p != &hotkey);
ParentKeys::<T>::insert(child.clone(), netuid, parents);
}

// --- 8. Log and return.
log::info!(
"RevokeChildrenMultiple( hotkey:{:?}, children:{:?}, netuid:{:?} )",
hotkey,
children,
netuid
);
Self::deposit_event(Event::RevokeChildrenMultiple(
hotkey.clone(),
children,
netuid,
));

// Ok and return.
Ok(())
}

/// Function which returns the amount of stake held by a hotkey on the network after applying
/// child/parent relationships.
///
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,7 @@ mod events {
HotkeyEmissionTempoSet(u64),
/// Multiple children were set for a hotkey
SetChildrenMultiple(T::AccountId, Vec<(u64, T::AccountId)>, u16),
/// Multiple children were revoked for a hotkey
RevokeChildrenMultiple(T::AccountId, Vec<T::AccountId>, u16),
}
}
54 changes: 54 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2303,6 +2303,60 @@ pub mod pallet {
Self::do_set_children_multiple(origin, hotkey, children_with_proportions, netuid)?;
Ok(().into())
}

/// Revoke multiple children for a given hotkey on a specified network.
///
/// This function allows a coldkey to revoke multiple children from a given hotkey on a specified network.
/// It removes the parent-child relationship for all specified children.
///
/// # Arguments:
/// * `origin` (OriginFor<T>):
/// - The signature of the calling coldkey. Revoking hotkey children can only be done by the coldkey.
///
/// * `hotkey` (T::AccountId):
/// - The hotkey from which the children will be revoked.
///
/// * `children` (Vec<T::AccountId>):
/// - A vector of AccountIds representing the children to be revoked.
///
/// * `netuid` (u16):
/// - The u16 network identifier where the childkeys exist.
///
/// # Events:
/// * `RevokeChildrenMultiple`:
/// - On successfully revoking multiple children from a hotkey.
///
/// # Errors:
/// * `SubNetworkDoesNotExist`:
/// - Attempting to revoke from a non-existent network.
/// * `NonAssociatedColdKey`:
/// - The coldkey does not own the hotkey.
/// * `HotKeyAccountNotExists`:
/// - The hotkey account does not exist.
///
/// # Workflow:
/// 1. Verify the transaction signature and ownership.
/// 2. Check that the specified network exists.
/// 3. Remove the specified children from the hotkey's children list.
/// 4. Remove the hotkey from each child's parent list.
/// 5. Update the storage for both ChildKeys and ParentKeys.
/// 6. Emit an event to log the operation.
///
/// # Note:
/// This function is more efficient than revoking children one by one, especially when dealing with multiple children.
#[pallet::call_index(69)]
#[pallet::weight((Weight::from_parts(119_000_000, 0)
.saturating_add(T::DbWeight::get().reads(6))
.saturating_add(T::DbWeight::get().writes(31)), DispatchClass::Operational, Pays::Yes))]
pub fn revoke_children_multiple(
origin: OriginFor<T>,
hotkey: T::AccountId,
children: Vec<T::AccountId>,
netuid: u16,
) -> DispatchResultWithPostInfo {
Self::do_revoke_children_multiple(origin, hotkey, children, netuid)?;
Ok(().into())
}
}

// ---- Subtensor helper functions.
Expand Down
Loading

0 comments on commit b33f55a

Please sign in to comment.