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

Feat/batch set weights #1022

Merged
merged 23 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
72 changes: 72 additions & 0 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,44 @@ mod dispatches {
}
}

/// --- Allows a hotkey to set weights for multiple netuids as a batch.
///
/// # Args:
/// * `origin`: (<T as frame_system::Config>Origin):
/// - The caller, a hotkey who wishes to set their weights.
///
/// * `netuids` (Vec<Compact<u16>>):
/// - The network uids we are setting these weights on.
///
/// * `weights` (Vec<Vec<(Compact<u16>, Compact<u16>)>):
/// - The weights to set for each network. [(uid, weight), ...]
///
/// * `version_keys` (Vec<Compact<u64>>):
/// - The network version keys to check if the validator is up to date.
///
/// # Event:
/// * WeightsSet;
/// - On successfully setting the weights on chain.
/// * BatchWeightsCompleted;
/// - On success of the batch.
/// * BatchCompletedWithErrors;
/// - On failure of any of the weights in the batch.
/// * BatchWeightItemFailed;
/// - On failure for each failed item in the batch.
///
#[pallet::call_index(80)]
#[pallet::weight((Weight::from_parts(22_060_000_000, 0)
.saturating_add(T::DbWeight::get().reads(4106))
.saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))]
pub fn batch_set_weights(
origin: OriginFor<T>,
netuids: Vec<Compact<u16>>,
weights: Vec<Vec<(Compact<u16>, Compact<u16>)>>,
version_keys: Vec<Compact<u64>>,
) -> DispatchResult {
Self::do_batch_set_weights(origin, netuids, weights, version_keys)
}

/// ---- Used to commit a hash of your weight values to later be revealed.
///
/// # Args:
Expand Down Expand Up @@ -124,6 +162,40 @@ mod dispatches {
Self::do_commit_weights(origin, netuid, commit_hash)
}

/// --- Allows a hotkey to commit weight hashes for multiple netuids as a batch.
///
/// # Args:
/// * `origin`: (<T as frame_system::Config>Origin):
/// - The caller, a hotkey who wishes to set their weights.
///
/// * `netuids` (Vec<Compact<u16>>):
/// - The network uids we are setting these weights on.
///
/// * `commit_hashes` (Vec<H256>):
/// - The commit hashes to commit.
///
/// # Event:
/// * WeightsSet;
/// - On successfully setting the weights on chain.
/// * BatchWeightsCompleted;
/// - On success of the batch.
/// * BatchCompletedWithErrors;
/// - On failure of any of the weights in the batch.
/// * BatchWeightItemFailed;
/// - On failure for each failed item in the batch.
///
#[pallet::call_index(99)]
#[pallet::weight((Weight::from_parts(46_000_000, 0)
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))]
pub fn batch_commit_weights(
origin: OriginFor<T>,
netuids: Vec<Compact<u16>>,
commit_hashes: Vec<H256>,
) -> DispatchResult {
Self::do_batch_commit_weights(origin, netuids, commit_hashes)
}

/// ---- Used to reveal the weights for a previously committed hash.
///
/// # Args:
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/macros/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ mod errors {
/// An axon or prometheus serving exceeded the rate limit for a registered neuron.
ServingRateLimitExceeded,
/// The caller is attempting to set weights with more UIDs than allowed.
UidsLengthExceedUidsInSubNet,
UidsLengthExceedUidsInSubNet, // 32
/// A transactor exceeded the rate limit for add network transaction.
NetworkTxRateLimitExceeded,
/// A transactor exceeded the rate limit for delegate transaction.
Expand Down
16 changes: 16 additions & 0 deletions pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use frame_support::pallet_macros::pallet_section;
/// This can later be imported into the pallet using [`import_section`].
#[pallet_section]
mod events {
use codec::Compact;

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
Expand Down Expand Up @@ -230,5 +232,19 @@ mod events {
/// - **netuid**: The network identifier.
/// - **revealed_hashes**: A vector of hashes representing each revealed weight set.
WeightsBatchRevealed(T::AccountId, u16, Vec<H256>),

/// A batch of weights (or commits) have been force-set.
///
/// - **netuids**: The netuids these weights were successfully set/committed for.
/// - **who**: The hotkey that set this batch.
BatchWeightsCompleted(Vec<Compact<u16>>, T::AccountId),

/// A batch extrinsic completed but with some errors.
BatchCompletedWithErrors(),

/// A weight set among a batch of weights failed.
///
/// - **error**: The dispatch error emitted by the failed item.
BatchWeightItemFailed(sp_runtime::DispatchError),
}
}
177 changes: 177 additions & 0 deletions pallets/subtensor/src/subnets/weights.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;
use crate::epoch::math::*;
use codec::Compact;
use sp_core::{ConstU32, H256};
use sp_runtime::{
traits::{BlakeTwo256, Hash},
Expand Down Expand Up @@ -108,6 +109,84 @@ impl<T: Config> Pallet<T> {
})
}

/// ---- The implementation for the extrinsic batch_commit_weights.
///
/// This call runs a batch of commit weights calls, continuing on errors.
///
/// # Args:
/// * 'origin': (<T as frame_system::Config>RuntimeOrigin):
/// - The signature of the calling hotkey.
///
/// * 'netuids' ( Vec<Compact<u16>> ):
/// - The u16 network identifiers.
///
/// * 'commit_hashes' ( Vec<H256> ):
/// - The commit hashes to be committed, one hash for each netuid in the batch.
///
/// # Event:
/// * WeightsCommitted;
/// - On successfully storing the weight hashes.
/// * BatchCompletedWithErrors;
/// - Emitted when at least on of the weight commits has an error.
/// * BatchWeightItemFailed;
/// - Emitted for each error within the batch.
/// * BatchWeightsCompleted
/// - Emitted when the batch of weights is completed.
/// * InputLengthsUnequal;
/// - Emitted when the lengths of the input vectors are not equal.
///
pub fn do_batch_commit_weights(
origin: T::RuntimeOrigin,
netuids: Vec<Compact<u16>>,
commit_hashes: Vec<H256>,
) -> dispatch::DispatchResult {
// --- 1. Check the caller's signature. This is the hotkey of a registered account.
let hotkey = ensure_signed(origin.clone())?;
log::debug!(
"do_batch_commit_weights( origin:{:?}, netuids:{:?}, hashes:{:?} )",
hotkey,
netuids,
commit_hashes
);

ensure!(
netuids.len() == commit_hashes.len(),
Error::<T>::InputLengthsUnequal
);

let results: Vec<dispatch::DispatchResult> = netuids
.iter()
.zip(commit_hashes.iter())
camfairchild marked this conversation as resolved.
Show resolved Hide resolved
.map(|(&netuid, &commit_hash)| {
let origin_cloned = origin.clone();

Self::do_commit_weights(origin_cloned, netuid.into(), commit_hash)
})
.collect();

let mut completed_with_errors: bool = false;
for result in results {
if let Some(err) = result.err() {
if !completed_with_errors {
Self::deposit_event(Event::BatchCompletedWithErrors());
completed_with_errors = true;
}
Self::deposit_event(Event::BatchWeightItemFailed(err));
}
}

// --- 19. Emit the tracking event.
log::debug!(
"BatchWeightsCompleted( netuids:{:?}, hotkey:{:?} )",
netuids,
hotkey
);
Self::deposit_event(Event::BatchWeightsCompleted(netuids, hotkey));

// --- 20. Return ok.
Ok(())
}

/// ---- The implementation for committing commit-reveal v3 weights.
///
/// # Args:
Expand Down Expand Up @@ -714,6 +793,104 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// ---- The implementation for the extrinsic batch_set_weights.
///
/// This call runs a batch of set weights calls, continuing on errors.
///
/// # Args:
/// * 'origin': (<T as frame_system::Config>RuntimeOrigin):
/// - The signature of the calling hotkey.
///
/// * 'netuids' ( Vec<Compact<u16>> ):
/// - The u16 network identifiers.
///
/// * 'weights' ( Vec<Vec<(Compact<u16>, Compact<u16>)>> ):
/// - Tuples of (uid, value) of the weights to be set on the chain,
/// one Vec for each netuid in the batch.
///
/// * 'version_keys' ( Vec<Compact<u64>> ):
/// - The network version key, one u64 for each netuid in the batch.
///
/// # Event:
/// * WeightsSet;
/// - On successfully setting the weights on chain.
/// * BatchCompletedWithErrors;
/// - Emitted when at least on of the weight sets has an error.
/// * BatchWeightItemFailed;
/// - Emitted for each error within the batch.
/// * BatchWeightsCompleted;
/// - Emitted when the batch of weights is completed.
/// * InputLengthsUnequal;
/// - Emitted when the lengths of the input vectors are not equal.
///
pub fn do_batch_set_weights(
origin: T::RuntimeOrigin,
netuids: Vec<Compact<u16>>,
weights: Vec<Vec<(Compact<u16>, Compact<u16>)>>,
version_keys: Vec<Compact<u64>>,
) -> dispatch::DispatchResult {
// --- 1. Check the caller's signature. This is the hotkey of a registered account.
let hotkey = ensure_signed(origin.clone())?;
log::debug!(
"do_batch_set_weights( origin:{:?} netuids:{:?}, weights:{:?}",
hotkey,
netuids,
weights
);

ensure!(
netuids.len() == weights.len() && netuids.len() == version_keys.len(),
Error::<T>::InputLengthsUnequal
);

let results: Vec<dispatch::DispatchResult> = netuids
.iter()
.zip(weights.iter())
.zip(version_keys.iter())
.map(|((&netuid, w), &version_key)| {
let origin_cloned = origin.clone();

if Self::get_commit_reveal_weights_enabled(netuid.into()) {
return Err(Error::<T>::CommitRevealEnabled.into());
}

let uids = w.iter().map(|(u, _)| (*u).into()).collect::<Vec<u16>>();

let values = w.iter().map(|(_, v)| (*v).into()).collect::<Vec<u16>>();

Self::do_set_weights(
origin_cloned,
netuid.into(),
uids,
values,
version_key.into(),
)
})
.collect();

let mut completed_with_errors: bool = false;
for result in results {
if let Some(err) = result.err() {
if !completed_with_errors {
Self::deposit_event(Event::BatchCompletedWithErrors());
completed_with_errors = true;
}
Self::deposit_event(Event::BatchWeightItemFailed(err));
}
}

// --- 19. Emit the tracking event.
log::debug!(
"BatchWeightsSet( netuids:{:?}, hotkey:{:?} )",
netuids,
hotkey
);
Self::deposit_event(Event::BatchWeightsCompleted(netuids, hotkey));

// --- 20. Return ok.
Ok(())
}

// ==========================
// ==== Helper functions ====
// ==========================
Expand Down
Loading
Loading