diff --git a/eco-tests/src/mock.rs b/eco-tests/src/mock.rs index e4fc547789..ede947ad15 100644 --- a/eco-tests/src/mock.rs +++ b/eco-tests/src/mock.rs @@ -142,7 +142,14 @@ impl system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; - type DispatchExtension = pallet_subtensor::CheckColdkeySwap; + type DispatchExtension = ( + pallet_subtensor::CheckColdkeySwap, + pallet_subtensor::CheckWeights, + pallet_subtensor::CheckRateLimits, + pallet_subtensor::CheckDelegateTake, + pallet_subtensor::CheckServingEndpoints, + pallet_subtensor::CheckEvmKeyAssociation, + ); } parameter_types! { diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 37db141bc8..809babaae9 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -4,27 +4,37 @@ use crate::Pallet as Subtensor; use crate::staking::lock::LockState; +use crate::subnets::mechanism::GLOBAL_MAX_SUBNET_COUNT; use crate::*; use codec::{Compact, Encode}; use frame_benchmarking::v2::*; -use frame_support::{StorageDoubleMap, assert_ok}; +use frame_support::{ + StorageDoubleMap, assert_ok, + dispatch::{DispatchInfo, PostDispatchInfo}, + traits::{Get, IsSubType, OriginTrait}, +}; use frame_system::{RawOrigin, pallet_prelude::BlockNumberFor}; pub use pallet::*; use sp_core::{H160, H256, ecdsa}; use sp_runtime::{ BoundedVec, Percent, - traits::{BlakeTwo256, Hash}, + traits::{BlakeTwo256, Dispatchable, Hash}, }; -use sp_std::collections::btree_set::BTreeSet; +use sp_std::collections::{btree_set::BTreeSet, vec_deque::VecDeque}; use sp_std::vec; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance}; +use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex, TaoBalance}; use subtensor_swap_interface::SwapHandler; #[benchmarks( where - T: pallet_balances::Config, + T: pallet_balances::Config + pallet_shield::Config, ::ExistentialDeposit: Get, + ::RuntimeCall: + Dispatchable, Info = DispatchInfo, PostInfo = PostDispatchInfo> + + IsSubType> + + IsSubType>, + OriginFor: Clone + OriginTrait, )] mod pallet_benchmarks { use super::*; @@ -85,6 +95,25 @@ mod pallet_benchmarks { ); } + fn set_benchmark_block_number(block_number: u64) { + let block_number: BlockNumberFor = match block_number.try_into() { + Ok(block_number) => block_number, + Err(_) => panic!("benchmark block number must fit into BlockNumberFor"), + }; + + frame_system::Pallet::::set_block_number(block_number); + } + + fn runtime_call(call: Call) -> ::RuntimeCall { + ::RuntimeCall::from(call).into() + } + + fn setup_extension_neuron(netuid: NetUid, hotkey: &T::AccountId) { + Subtensor::::init_new_network(netuid, 0); + Subtensor::::set_max_allowed_uids(netuid, GLOBAL_MAX_SUBNET_COUNT); + Subtensor::::append_neuron(netuid, hotkey, 0); + } + fn benchmark_evm_secret_key() -> libsecp256k1::SecretKey { let seed = [42u8; 32]; @@ -2298,6 +2327,157 @@ mod pallet_benchmarks { _(RawOrigin::Signed(coldkey.clone()), netuid); } + #[benchmark] + fn check_coldkey_swap_extension() { + let coldkey: T::AccountId = account("coldkey", 0, 1); + let new_coldkey: T::AccountId = account("new_coldkey", 0, 1); + let hotkey: T::AccountId = account("hotkey", 0, 1); + let new_coldkey_hash: T::Hash = ::Hashing::hash_of(&new_coldkey); + let now = frame_system::Pallet::::block_number(); + let call = runtime_call::(Call::::register_network { hotkey }); + + ColdkeySwapAnnouncements::::insert(&coldkey, (now, new_coldkey_hash)); + ColdkeySwapDisputes::::insert(&coldkey, now); + + #[block] + { + assert_eq!( + CheckColdkeySwap::::check(&coldkey, &call), + Err(Error::::ColdkeySwapDisputed) + ); + } + } + + #[benchmark] + fn check_weights_extension() { + let netuid = NetUid::from(1); + let hotkey: T::AccountId = account("hotkey", 0, 1); + let netuid_index = NetUidStorageIndex::from(netuid); + let uids: Vec = vec![0]; + let values: Vec = vec![10]; + let salt: Vec = vec![8]; + let version_key = 0_u64; + + setup_extension_neuron::(netuid, &hotkey); + Subtensor::::set_stake_threshold(0); + + let commit_hash = Subtensor::::get_commit_hash( + &hotkey, + netuid_index, + &uids, + &values, + &salt, + version_key, + ); + let mut commits = VecDeque::new(); + for i in 0..9 { + commits.push_back((H256::repeat_byte(i + 1), 0, 0, 0)); + } + commits.push_back((commit_hash, 0, 0, 0)); + WeightCommits::::insert(netuid_index, &hotkey, commits); + + let reveal_period = Subtensor::::get_reveal_period(netuid); + SubnetEpochIndex::::insert(netuid, reveal_period); + + let call = Call::::reveal_weights { + netuid, + uids, + values, + salt, + version_key, + }; + + #[block] + { + assert_ok!(CheckWeights::::check(&hotkey, &call)); + } + } + + #[benchmark] + fn check_rate_limits_extension() { + let netuid = NetUid::from(1); + let hotkey: T::AccountId = account("hotkey", 0, 1); + let netuid_index = NetUidStorageIndex::from(netuid); + let call = Call::::set_weights { + netuid, + dests: vec![0], + weights: vec![1], + version_key: 0, + }; + + setup_extension_neuron::(netuid, &hotkey); + Subtensor::::set_commit_reveal_weights_enabled(netuid, false); + Subtensor::::set_weights_set_rate_limit(netuid, 1); + Subtensor::::set_last_update_for_uid(netuid_index, 0, 1); + set_benchmark_block_number::(3); + + #[block] + { + assert_ok!(CheckRateLimits::::check(&hotkey, &call)); + } + } + + #[benchmark] + fn check_delegate_take_extension() { + let coldkey: T::AccountId = account("coldkey", 0, 1); + let hotkey: T::AccountId = account("hotkey", 0, 1); + let call = Call::::increase_take { + hotkey: hotkey.clone(), + take: Subtensor::::get_max_delegate_take(), + }; + + Owner::::insert(&hotkey, &coldkey); + + #[block] + { + assert_ok!(CheckDelegateTake::::check(&coldkey, &call)); + } + } + + #[benchmark] + fn check_serving_endpoints_extension() { + let hotkey: T::AccountId = account("hotkey", 0, 1); + let netuid = NetUid::from(1); + let call = Call::::serve_axon { + netuid, + version: 1, + ip: u128::from(u32::from_be_bytes([8, 8, 8, 8])), + port: 1, + ip_type: 4, + protocol: 0, + placeholder1: 0, + placeholder2: 0, + }; + + Uids::::insert(netuid, &hotkey, 0); + + #[block] + { + assert_ok!(CheckServingEndpoints::::check(&hotkey, &call)); + } + } + + #[benchmark] + fn check_evm_key_association_extension() { + let netuid = NetUid::from(1); + let hotkey: T::AccountId = account("hotkey", 0, 1); + let block_number = T::EvmKeyAssociateRateLimit::get().saturating_add(1); + let call = Call::::associate_evm_key { + netuid, + evm_key: H160::zero(), + block_number, + signature: ecdsa::Signature::from_raw([0_u8; 65]), + }; + + setup_extension_neuron::(netuid, &hotkey); + set_benchmark_block_number::(block_number); + + #[block] + { + assert_ok!(CheckEvmKeyAssociation::::check(&hotkey, &call)); + } + } + impl_benchmark_test_suite!( Subtensor, crate::tests::mock::new_test_ext(1), diff --git a/pallets/subtensor/src/extensions/subtensor.rs b/pallets/subtensor/src/extensions/subtensor.rs index 39c6c4e011..ea91c87c6e 100644 --- a/pallets/subtensor/src/extensions/subtensor.rs +++ b/pallets/subtensor/src/extensions/subtensor.rs @@ -1,24 +1,65 @@ -use crate::{BalancesCall, Call, Config, Error, Pallet, TransactionType}; +use crate::{ + Call, CheckColdkeySwap, CheckDelegateTake, CheckEvmKeyAssociation, CheckRateLimits, + CheckServingEndpoints, CheckWeights, Config, Error, +}; use codec::{Decode, DecodeWithMemTracking, Encode}; -use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; -use frame_support::traits::IsSubType; +use frame_support::{ + dispatch::{DispatchExtension, DispatchInfo, PostDispatchInfo}, + traits::{IsSubType, OriginTrait}, + weights::Weight, +}; use scale_info::TypeInfo; use sp_runtime::traits::{ - AsSystemOriginSigner, DispatchInfoOf, Dispatchable, Implication, TransactionExtension, - ValidateResult, + DispatchInfoOf, Dispatchable, Implication, TransactionExtension, ValidateResult, }; use sp_runtime::{ impl_tx_ext_default, - transaction_validity::{TransactionSource, TransactionValidity, ValidTransaction}, + transaction_validity::{TransactionSource, TransactionValidityError}, }; use sp_std::marker::PhantomData; -use sp_std::vec::Vec; use subtensor_macros::freeze_struct; -use subtensor_runtime_common::{CustomTransactionError, NetUid, NetUidStorageIndex}; +use subtensor_runtime_common::CustomTransactionError; type CallOf = ::RuntimeCall; type OriginOf = ::RuntimeOrigin; +#[allow(deprecated)] +impl From> for CustomTransactionError { + fn from(error: Error) -> Self { + match error { + Error::::AmountTooLow | Error::::NotEnoughStakeToSetWeights => { + Self::StakeAmountTooLow + } + Error::::SubnetNotExists => Self::SubnetNotExists, + Error::::NotEnoughBalanceToStake => Self::BalanceTooLow, + Error::::HotKeyAccountNotExists => Self::HotkeyAccountDoesntExist, + Error::::NotEnoughStakeToWithdraw => Self::NotEnoughStakeToWithdraw, + Error::::InsufficientLiquidity => Self::InsufficientLiquidity, + Error::::SlippageTooHigh => Self::SlippageTooHigh, + Error::::TransferDisallowed => Self::TransferDisallowed, + Error::::HotKeyNotRegisteredInNetwork => Self::HotKeyNotRegisteredInNetwork, + Error::::InvalidIpAddress => Self::InvalidIpAddress, + Error::::ServingRateLimitExceeded => Self::ServingRateLimitExceeded, + Error::::InvalidPort => Self::InvalidPort, + Error::::NonAssociatedColdKey => Self::NonAssociatedColdKey, + Error::::DelegateTakeTooLow => Self::DelegateTakeTooLow, + Error::::DelegateTakeTooHigh => Self::DelegateTakeTooHigh, + Error::::InputLengthsUnequal => Self::InputLengthsUnequal, + Error::::NoWeightsCommitFound => Self::CommitNotFound, + Error::::RevealTooEarly => Self::CommitBlockNotInRevealRange, + Error::::InvalidRevealRound => Self::InvalidRevealRound, + Error::::CommittingWeightsTooFast + | Error::::SettingWeightsTooFast + | Error::::NetworkTxRateLimitExceeded => Self::RateLimitExceeded, + Error::::HotKeyNotRegisteredInSubNet => Self::UidNotFound, + Error::::EvmKeyAssociateRateLimitExceeded => Self::EvmKeyAssociateRateLimitExceeded, + Error::::ColdkeySwapAnnounced => Self::ColdkeyInSwapSchedule, + Error::::ColdkeySwapDisputed => Self::ColdkeySwapDisputed, + _ => Self::BadRequest, + } + } +} + #[freeze_struct("2e02eb32e5cb25d3")] #[derive(Default, Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)] pub struct SubtensorTransactionExtension(pub PhantomData); @@ -29,87 +70,44 @@ impl sp_std::fmt::Debug for SubtensorTransac } } -impl SubtensorTransactionExtension -where - CallOf: Dispatchable + IsSubType>, -{ +impl SubtensorTransactionExtension { pub fn new() -> Self { Self(Default::default()) } - pub fn validity_ok(priority: u64) -> ValidTransaction { - ValidTransaction { - priority, - ..Default::default() - } - } - pub fn check_weights_min_stake(who: &T::AccountId, netuid: NetUid) -> bool { - Pallet::::check_weights_min_stake(who, netuid) - } + fn check(origin: &OriginOf, call: &CallOf) -> Result<(), Error> + where + T: pallet_shield::Config, + CallOf: Dispatchable> + + IsSubType> + + IsSubType>, + OriginOf: OriginTrait, + { + let Some(who) = origin.as_signer() else { + return Ok(()); + }; - /// Mirror the per-neuron `WeightsSetRateLimit` throttle (otherwise only - /// enforced inside the dispatch body) into the transaction-validity gate so - /// over-rate `set_weights`/`commit_weights` transactions are rejected - /// pre-dispatch instead of being included for free (these calls are - /// `Pays::No`). Unregistered callers (whose UID cannot be resolved) pass - /// through here and are rejected by the dispatch body, preserving existing - /// error semantics. - pub fn check_weights_rate_limit( - who: &T::AccountId, - netuid: NetUid, - netuid_index: NetUidStorageIndex, - ) -> Result<(), CustomTransactionError> { - if let Ok(neuron_uid) = Pallet::::get_uid_for_net_and_hotkey(netuid, who) { - let current_block = Pallet::::get_current_block_as_u64(); - if !Pallet::::check_rate_limit(netuid_index, neuron_uid, current_block) { - return Err(CustomTransactionError::RateLimitExceeded); - } - } - Ok(()) - } + CheckColdkeySwap::::check(who, call)?; - pub fn result_to_validity(result: Result<(), Error>, priority: u64) -> TransactionValidity { - match result { - Ok(()) => Ok(ValidTransaction { - priority, - ..Default::default() - }), - Err(err) => Err(match err { - Error::::AmountTooLow => CustomTransactionError::StakeAmountTooLow, - Error::::SubnetNotExists => CustomTransactionError::SubnetNotExists, - Error::::NotEnoughBalanceToStake => CustomTransactionError::BalanceTooLow, - Error::::HotKeyAccountNotExists => { - CustomTransactionError::HotkeyAccountDoesntExist - } - Error::::NotEnoughStakeToWithdraw => { - CustomTransactionError::NotEnoughStakeToWithdraw - } - Error::::InsufficientLiquidity => CustomTransactionError::InsufficientLiquidity, - Error::::SlippageTooHigh => CustomTransactionError::SlippageTooHigh, - Error::::TransferDisallowed => CustomTransactionError::TransferDisallowed, - Error::::HotKeyNotRegisteredInNetwork => { - CustomTransactionError::HotKeyNotRegisteredInNetwork - } - Error::::InvalidIpAddress => CustomTransactionError::InvalidIpAddress, - Error::::ServingRateLimitExceeded => { - CustomTransactionError::ServingRateLimitExceeded - } - Error::::InvalidPort => CustomTransactionError::InvalidPort, - Error::::NonAssociatedColdKey => CustomTransactionError::NonAssociatedColdKey, - _ => CustomTransactionError::BadRequest, - } - .into()), - } + let Some(call) = call.is_sub_type() else { + return Ok(()); + }; + + CheckWeights::::check(who, call)?; + CheckRateLimits::::check(who, call)?; + CheckDelegateTake::::check(who, call)?; + CheckServingEndpoints::::check(who, call)?; + CheckEvmKeyAssociation::::check(who, call) } } impl TransactionExtension> for SubtensorTransactionExtension where - T: Config + Send + Sync + TypeInfo + pallet_balances::Config, - CallOf: Dispatchable + T: Config + pallet_shield::Config + Send + Sync + TypeInfo, + CallOf: Dispatchable, Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType> - + IsSubType>, - OriginOf: AsSystemOriginSigner + Clone, + + IsSubType>, + OriginOf: Clone + OriginTrait, { const IDENTIFIER: &'static str = "SubtensorTransactionExtension"; @@ -117,6 +115,16 @@ where type Val = (); type Pre = (); + fn weight(&self, call: &CallOf) -> Weight { + use DispatchExtension as DE; + as DE>>::weight(call) + .saturating_add( as DE>>::weight(call)) + .saturating_add( as DE>>::weight(call)) + .saturating_add( as DE>>::weight(call)) + .saturating_add( as DE>>::weight(call)) + .saturating_add( as DE>>::weight(call)) + } + fn validate( &self, origin: OriginOf, @@ -127,331 +135,164 @@ where _inherited_implication: &impl Implication, _source: TransactionSource, ) -> ValidateResult> { - // Ensure the transaction is signed, else we just skip the extension. - let Some(who) = origin.as_system_origin_signer() else { - return Ok((Default::default(), (), origin)); - }; + Self::check(&origin, call) + .map(|()| (Default::default(), (), origin)) + .map_err(|error| TransactionValidityError::from(CustomTransactionError::from(error))) + } - match call.is_sub_type() { - Some(Call::commit_weights { netuid, .. }) => { - if !Self::check_weights_min_stake(who, *netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - // Mirror the in-dispatch commit rate limit - // (internal_commit_weights always enforces it). - Self::check_weights_rate_limit(who, *netuid, NetUidStorageIndex::from(*netuid))?; - Ok((Default::default(), (), origin)) - } - Some(Call::commit_mechanism_weights { netuid, mecid, .. }) => { - if !Self::check_weights_min_stake(who, *netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - // Mirror the in-dispatch commit rate limit - // (internal_commit_weights always enforces it). - Self::check_weights_rate_limit( - who, - *netuid, - Pallet::::get_mechanism_storage_index(*netuid, *mecid), - )?; - Ok((Default::default(), (), origin)) - } - Some(Call::batch_commit_weights { - netuids, - commit_hashes, - }) => { - if netuids.len() != commit_hashes.len() { - return Err(CustomTransactionError::InputLengthsUnequal.into()); - } - for netuid in netuids.iter() { - let netuid: NetUid = (*netuid).into(); - if !Self::check_weights_min_stake(who, netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - } - Ok((Default::default(), (), origin)) - } - Some(Call::reveal_weights { - netuid, - uids, - values, - salt, - version_key, - }) => { - if !Self::check_weights_min_stake(who, *netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - let provided_hash = Pallet::::get_commit_hash( - who, - NetUidStorageIndex::from(*netuid), - uids, - values, - salt, - *version_key, - ); - match Pallet::::find_commit_epoch_via_hash(provided_hash) { - Some(commit_epoch) => { - if Pallet::::is_reveal_block_range(*netuid, commit_epoch) { - Ok((Default::default(), (), origin)) - } else { - Err(CustomTransactionError::CommitBlockNotInRevealRange.into()) - } - } - None => Err(CustomTransactionError::CommitNotFound.into()), - } - } - Some(Call::reveal_mechanism_weights { - netuid, - mecid, - uids, - values, - salt, - version_key, - }) => { - if !Self::check_weights_min_stake(who, *netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - let provided_hash = Pallet::::get_commit_hash( - who, - Pallet::::get_mechanism_storage_index(*netuid, *mecid), - uids, - values, - salt, - *version_key, - ); - match Pallet::::find_commit_epoch_via_hash(provided_hash) { - Some(commit_epoch) => { - if Pallet::::is_reveal_block_range(*netuid, commit_epoch) { - Ok((Default::default(), (), origin)) - } else { - Err(CustomTransactionError::CommitBlockNotInRevealRange.into()) - } - } - None => Err(CustomTransactionError::CommitNotFound.into()), - } - } - Some(Call::batch_reveal_weights { - netuid, - uids_list, - values_list, - salts_list, - version_keys, - }) => { - if !Self::check_weights_min_stake(who, *netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } + impl_tx_ext_default!(CallOf; prepare); +} - let num_reveals = uids_list.len(); - if num_reveals == values_list.len() - && num_reveals == salts_list.len() - && num_reveals == version_keys.len() - { - let provided_hashes = (0..num_reveals) - .map(|i| { - Pallet::::get_commit_hash( - who, - NetUidStorageIndex::from(*netuid), - uids_list.get(i).unwrap_or(&Vec::new()), - values_list.get(i).unwrap_or(&Vec::new()), - salts_list.get(i).unwrap_or(&Vec::new()), - *version_keys.get(i).unwrap_or(&0_u64), - ) - }) - .collect::>(); +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod tests { + use super::SubtensorTransactionExtension; + use crate::{ + CheckColdkeySwap, CheckDelegateTake, CheckEvmKeyAssociation, CheckRateLimits, + CheckServingEndpoints, CheckWeights, ColdkeySwapAnnouncements, ColdkeySwapDisputes, + tests::mock::*, + }; + use frame_support::{ + assert_ok, + dispatch::{DispatchExtension, GetDispatchInfo, Pays}, + }; + use frame_system::RawOrigin; + use sp_core::U256; + use sp_runtime::{ + traits::{DispatchInfoOf, Hash, TransactionExtension, TxBaseImplication}, + transaction_validity::{TransactionSource, TransactionValidityError, ValidTransaction}, + }; + use subtensor_runtime_common::{CustomTransactionError, MechId, NetUid}; - let batch_reveal_epoch = provided_hashes - .iter() - .filter_map(|hash| Pallet::::find_commit_epoch_via_hash(*hash)) - .collect::>(); + fn dispatch_info() + -> sp_runtime::traits::DispatchInfoOf<::RuntimeCall> { + DispatchInfoOf::<::RuntimeCall>::default() + } - if provided_hashes.len() == batch_reveal_epoch.len() { - if Pallet::::is_batch_reveal_epoch_range(*netuid, batch_reveal_epoch) { - Ok((Default::default(), (), origin)) - } else { - Err(CustomTransactionError::CommitBlockNotInRevealRange.into()) - } - } else { - Err(CustomTransactionError::CommitNotFound.into()) - } - } else { - Err(CustomTransactionError::InputLengthsUnequal.into()) - } - } - Some(Call::set_weights { netuid, .. }) => { - if !Self::check_weights_min_stake(who, *netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - // Mirror the in-dispatch rate limit (only enforced when - // commit-reveal is disabled, matching internal_set_weights). - if !Pallet::::get_commit_reveal_weights_enabled(*netuid) { - Self::check_weights_rate_limit( - who, - *netuid, - NetUidStorageIndex::from(*netuid), - )?; - } - Ok((Default::default(), (), origin)) - } - Some(Call::set_mechanism_weights { netuid, mecid, .. }) => { - if !Self::check_weights_min_stake(who, *netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - // Mirror the in-dispatch rate limit (only enforced when - // commit-reveal is disabled, matching internal_set_weights). - if !Pallet::::get_commit_reveal_weights_enabled(*netuid) { - Self::check_weights_rate_limit( - who, - *netuid, - Pallet::::get_mechanism_storage_index(*netuid, *mecid), - )?; - } - Ok((Default::default(), (), origin)) - } - Some(Call::batch_set_weights { - netuids, - weights, - version_keys, - }) => { - if netuids.len() != weights.len() || netuids.len() != version_keys.len() { - return Err(CustomTransactionError::InputLengthsUnequal.into()); - } - for netuid in netuids.iter() { - let netuid: NetUid = (*netuid).into(); - if !Self::check_weights_min_stake(who, netuid) { - return Err(CustomTransactionError::StakeAmountTooLow.into()); - } - } - Ok((Default::default(), (), origin)) - } - Some(Call::commit_timelocked_weights { - netuid, - reveal_round, - .. - }) => { - if Self::check_weights_min_stake(who, *netuid) { - if *reveal_round < pallet_drand::LastStoredRound::::get() { - return Err(CustomTransactionError::InvalidRevealRound.into()); - } - Ok((Default::default(), (), origin)) - } else { - Err(CustomTransactionError::StakeAmountTooLow.into()) - } - } - Some(Call::commit_timelocked_mechanism_weights { - netuid, - mecid: _, - reveal_round, - .. - }) - | Some(Call::commit_crv3_mechanism_weights { - netuid, - mecid: _, - reveal_round, - .. - }) => { - if Self::check_weights_min_stake(who, *netuid) { - if *reveal_round < pallet_drand::LastStoredRound::::get() { - return Err(CustomTransactionError::InvalidRevealRound.into()); - } - Ok((Default::default(), (), origin)) - } else { - Err(CustomTransactionError::StakeAmountTooLow.into()) - } - } - Some(Call::increase_take { hotkey, take }) - | Some(Call::decrease_take { hotkey, take }) => { - if *take < Pallet::::get_min_delegate_take() { - return Err(CustomTransactionError::DelegateTakeTooLow.into()); - } - if *take > Pallet::::get_max_delegate_take() { - return Err(CustomTransactionError::DelegateTakeTooHigh.into()); - } - Self::result_to_validity(Pallet::::do_take_checks(who, hotkey), 0u64) - .map(|validity| (validity, (), origin.clone())) - } + fn validate_signed( + signer: U256, + call: &RuntimeCall, + ) -> Result { + SubtensorTransactionExtension::::new() + .validate( + RawOrigin::Signed(signer).into(), + call, + &dispatch_info(), + 0, + (), + &TxBaseImplication(()), + TransactionSource::External, + ) + .map(|(validity, _, _)| validity) + } - Some(Call::serve_axon { - netuid, - version, - ip, - port, - ip_type, - protocol, - placeholder1, - placeholder2, - }) => { - // Fully validate the user input - Self::result_to_validity( - Pallet::::validate_serve_axon( - who, - *netuid, - *version, - *ip, - *port, - *ip_type, - *protocol, - *placeholder1, - *placeholder2, - ), - 0u64, - ) - .map(|validity| (validity, (), origin.clone())) - } - Some(Call::serve_axon_tls { + fn expected_transaction_extension_weight(call: &RuntimeCall) -> frame_support::weights::Weight { + use DispatchExtension as DE; + as DE>::weight(call) + .saturating_add( as DE>::weight(call)) + .saturating_add( as DE>::weight(call)) + .saturating_add( as DE>::weight(call)) + .saturating_add( as DE>::weight( + call, + )) + .saturating_add( as DE>::weight( + call, + )) + } + + #[test] + fn validate_accepts_calls_allowed_by_dispatch_extensions() { + new_test_ext(1).execute_with(|| { + let call = RuntimeCall::System(frame_system::Call::remark { remark: vec![] }); + + assert_ok!(validate_signed(U256::from(1), &call)); + }); + } + + #[test] + #[allow(deprecated)] + fn validate_maps_dispatch_extension_errors_to_transaction_errors() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let call = RuntimeCall::System(frame_system::Call::remark { remark: vec![] }); + let new_coldkey_hash = + ::Hashing::hash_of(&U256::from(99)); + + ColdkeySwapAnnouncements::::insert( + coldkey, + (System::block_number(), new_coldkey_hash), + ); + let err = validate_signed(coldkey, &call).unwrap_err(); + assert_eq!(err, CustomTransactionError::ColdkeyInSwapSchedule.into()); + + ColdkeySwapDisputes::::insert(coldkey, System::block_number()); + let err = validate_signed(coldkey, &call).unwrap_err(); + assert_eq!(err, CustomTransactionError::ColdkeySwapDisputed.into()); + }); + } + + #[test] + fn pays_no_set_weights_validate_rejects_rate_limited_call() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + + add_network_disable_commit_reveal(netuid, 1, 0); + setup_reserves( netuid, - version, - ip, - port, - ip_type, - protocol, - placeholder1, - placeholder2, - certificate: _, - }) => Self::result_to_validity( - Pallet::::validate_serve_axon( - who, - *netuid, - *version, - *ip, - *port, - *ip_type, - *protocol, - *placeholder1, - *placeholder2, - ), - 0u64, - ) - .map(|validity| (validity, (), origin.clone())), - Some(Call::serve_prometheus { + 1_000_000_000_000_u64.into(), + 1_000_000_000_000_u64.into(), + ); + register_ok_neuron(netuid, hotkey, coldkey, 0); + SubtensorModule::set_stake_threshold(0); + + SubtensorModule::set_weights_set_rate_limit(netuid, 100); + System::set_block_number(10_u64); + let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); + let netuid_index = SubtensorModule::get_mechanism_storage_index(netuid, MechId::MAIN); + SubtensorModule::set_last_update_for_uid( + netuid_index, + uid, + SubtensorModule::get_current_block_as_u64(), + ); + + let call = RuntimeCall::SubtensorModule(SubtensorCall::set_weights { netuid, - version, - ip, - port, - ip_type, - }) => Self::result_to_validity( - Pallet::::validate_serve_prometheus( - who, *netuid, *version, *ip, *port, *ip_type, - ) - .map(|_| ()), - 0u64, - ) - .map(|validity| (validity, (), origin.clone())), - Some(Call::register_network { .. }) => { - if !TransactionType::RegisterNetwork.passes_rate_limit::(who) { - return Err(CustomTransactionError::RateLimitExceeded.into()); - } + dests: vec![uid], + weights: vec![1], + version_key: 0, + }); - Ok((Default::default(), (), origin)) - } - Some(Call::associate_evm_key { netuid, .. }) => { - let uid = Pallet::::get_uid_for_net_and_hotkey(*netuid, who) - .map_err(|_| CustomTransactionError::UidNotFound)?; - Pallet::::ensure_evm_key_associate_rate_limit(*netuid, uid) - .map_err(|_| CustomTransactionError::EvmKeyAssociateRateLimitExceeded)?; - Ok((Default::default(), (), origin)) - } - _ => Ok((Default::default(), (), origin)), - } + assert_eq!(call.get_dispatch_info().pays_fee, Pays::No); + let err = validate_signed(hotkey, &call).unwrap_err(); + assert_eq!(err, CustomTransactionError::RateLimitExceeded.into()); + }); } - impl_tx_ext_default!(CallOf; weight prepare); + #[test] + fn weight_matches_top_level_dispatch_extension_checks() { + new_test_ext(1).execute_with(|| { + let extension = SubtensorTransactionExtension::::new(); + let calls = [ + RuntimeCall::System(frame_system::Call::remark { remark: vec![] }), + RuntimeCall::SubtensorModule(SubtensorCall::set_weights { + netuid: NetUid::from(1), + dests: vec![0], + weights: vec![1], + version_key: 0, + }), + RuntimeCall::SubtensorModule(SubtensorCall::register_network { + hotkey: U256::from(9), + }), + ]; + + for call in calls { + assert_eq!( + TransactionExtension::weight(&extension, &call), + expected_transaction_extension_weight(&call) + ); + } + }); + } } diff --git a/pallets/subtensor/src/guards/check_coldkey_swap.rs b/pallets/subtensor/src/guards/check_coldkey_swap.rs index 14b1a25ac9..5f124be219 100644 --- a/pallets/subtensor/src/guards/check_coldkey_swap.rs +++ b/pallets/subtensor/src/guards/check_coldkey_swap.rs @@ -1,3 +1,4 @@ +use crate::weights::WeightInfo; use crate::{Call, ColdkeySwapAnnouncements, ColdkeySwapDisputes, Config, Error}; use frame_support::{ dispatch::{DispatchErrorWithPostInfo, DispatchExtension, DispatchInfo, PostDispatchInfo}, @@ -26,6 +27,43 @@ type DispatchableOriginOf = as Dispatchable>::RuntimeOrigin; /// resolved origin. pub struct CheckColdkeySwap(PhantomData); +impl CheckColdkeySwap +where + T: Config + pallet_shield::Config, + CallOf: IsSubType> + IsSubType>, +{ + pub fn check(who: &T::AccountId, call: &CallOf) -> Result<(), Error> { + if !ColdkeySwapAnnouncements::::contains_key(who) { + return Ok(()); + } + + if ColdkeySwapDisputes::::contains_key(who) { + return Err(Error::::ColdkeySwapDisputed); + } + + if Self::is_allowed_during_swap(call) { + Ok(()) + } else { + Err(Error::::ColdkeySwapAnnounced) + } + } + + fn is_allowed_during_swap(call: &CallOf) -> bool { + matches!( + call.is_sub_type(), + Some( + Call::announce_coldkey_swap { .. } + | Call::swap_coldkey_announced { .. } + | Call::dispute_coldkey_swap { .. } + | Call::clear_coldkey_swap_announcement { .. } + ) + ) || matches!( + IsSubType::>::is_sub_type(call), + Some(pallet_shield::Call::submit_encrypted { .. }) + ) + } +} + impl DispatchExtension<::RuntimeCall> for CheckColdkeySwap where T: Config + pallet_shield::Config, @@ -37,7 +75,7 @@ where type Pre = (); fn weight(_call: &CallOf) -> Weight { - T::DbWeight::get().reads(2) + ::WeightInfo::check_coldkey_swap_extension() } fn pre_dispatch( @@ -50,44 +88,22 @@ where return Ok(()); }; - if ColdkeySwapAnnouncements::::contains_key(who) { - if ColdkeySwapDisputes::::contains_key(who) { - return Err(Error::::ColdkeySwapDisputed.into()); - } - - let is_allowed_direct = matches!( - call.is_sub_type(), - Some( - Call::announce_coldkey_swap { .. } - | Call::swap_coldkey_announced { .. } - | Call::dispute_coldkey_swap { .. } - | Call::clear_coldkey_swap_announcement { .. } - ) - ); - - let is_mev_protected = matches!( - IsSubType::>::is_sub_type(call), - Some(pallet_shield::Call::submit_encrypted { .. }) - ); - - if !is_allowed_direct && !is_mev_protected { - return Err(Error::::ColdkeySwapAnnounced.into()); - } - } - - Ok(()) + Self::check(who, call).map_err(Into::into) } } #[cfg(test)] #[allow(clippy::expect_used, clippy::unwrap_used)] mod tests { + use super::CheckColdkeySwap; use crate::{ColdkeySwapAnnouncements, ColdkeySwapDisputes, Error, tests::mock::*}; - use frame_support::{BoundedVec, assert_ok}; + use frame_support::{ + BoundedVec, assert_ok, dispatch::DispatchResultWithPostInfo, traits::ExtendedDispatchable, + }; use frame_system::Call as SystemCall; use pallet_subtensor_proxy::Call as ProxyCall; use sp_core::U256; - use sp_runtime::traits::{Dispatchable, Hash}; + use sp_runtime::traits::Hash; use subtensor_runtime_common::{ProxyType, TaoBalance}; type HashingOf = ::Hashing; @@ -154,11 +170,17 @@ mod tests { let _ = SubtensorModule::spend_tao(coldkey, credit, tao).unwrap(); } + fn dispatch_with_ext(call: RuntimeCall, origin: RuntimeOrigin) -> DispatchResultWithPostInfo { + as ExtendedDispatchable>::dispatch_with_extension( + origin, call, + ) + } + #[test] fn no_active_swap_allows_calls() { new_test_ext(1).execute_with(|| { let who = U256::from(1); - assert_ok!(remark_call().dispatch(RuntimeOrigin::signed(who))); + assert_ok!(dispatch_with_ext(remark_call(), RuntimeOrigin::signed(who))); }); } @@ -167,8 +189,7 @@ mod tests { new_test_ext(1).execute_with(|| { let who = U256::from(1); setup_swap_disputed(&who); - - assert_ok!(remark_call().dispatch(RuntimeOrigin::none())); + assert_ok!(dispatch_with_ext(remark_call(), RuntimeOrigin::none())); }); } @@ -177,8 +198,7 @@ mod tests { new_test_ext(1).execute_with(|| { let who = U256::from(1); setup_swap_disputed(&who); - - assert_ok!(remark_call().dispatch(RuntimeOrigin::root())); + assert_ok!(dispatch_with_ext(remark_call(), RuntimeOrigin::root())); }); } @@ -190,7 +210,9 @@ mod tests { for call in forbidden_calls() { assert_eq!( - call.dispatch(RuntimeOrigin::signed(who)).unwrap_err().error, + dispatch_with_ext(call, RuntimeOrigin::signed(who)) + .unwrap_err() + .error, Error::::ColdkeySwapAnnounced.into() ); } @@ -204,7 +226,7 @@ mod tests { setup_swap_announced(&who); for call in authorized_calls() { - if let Err(err) = call.dispatch(RuntimeOrigin::signed(who)) { + if let Err(err) = dispatch_with_ext(call, RuntimeOrigin::signed(who)) { assert_ne!( err.error, Error::::ColdkeySwapAnnounced.into(), @@ -229,7 +251,9 @@ mod tests { for call in all_calls { assert_eq!( - call.dispatch(RuntimeOrigin::signed(who)).unwrap_err().error, + dispatch_with_ext(call, RuntimeOrigin::signed(who)) + .unwrap_err() + .error, Error::::ColdkeySwapDisputed.into() ); } @@ -265,7 +289,10 @@ mod tests { }); // The outer proxy call itself succeeds - assert_ok!(proxy_call.dispatch(RuntimeOrigin::signed(delegate))); + assert_ok!(dispatch_with_ext( + proxy_call, + RuntimeOrigin::signed(delegate) + )); // The inner call was blocked — check via LastCallResult storage. assert_eq!( @@ -315,7 +342,10 @@ mod tests { call: Box::new(inner_proxy), }); - assert_ok!(outer_proxy.dispatch(RuntimeOrigin::signed(delegate2))); + assert_ok!(dispatch_with_ext( + outer_proxy, + RuntimeOrigin::signed(delegate2) + )); // The innermost call (remark as real) was blocked. assert_eq!( diff --git a/pallets/subtensor/src/guards/check_delegate_take.rs b/pallets/subtensor/src/guards/check_delegate_take.rs new file mode 100644 index 0000000000..c9f54d4cb5 --- /dev/null +++ b/pallets/subtensor/src/guards/check_delegate_take.rs @@ -0,0 +1,192 @@ +use crate::weights::WeightInfo; +use crate::{Call, Config, Error, Pallet}; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, DispatchExtension, DispatchInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::{IsSubType, OriginTrait}, +}; +use sp_runtime::traits::Dispatchable; +use sp_std::marker::PhantomData; + +type CallOf = ::RuntimeCall; +type DispatchableOriginOf = as Dispatchable>::RuntimeOrigin; + +/// Dispatch extension for delegate-take bounds and ownership preconditions. +/// +/// Signed increase/decrease take calls are checked before dispatch; unrelated +/// calls and non-signed origins pass through. +pub struct CheckDelegateTake(PhantomData); + +impl CheckDelegateTake { + pub fn check(who: &T::AccountId, call: &Call) -> Result<(), Error> { + match call { + Call::increase_take { hotkey, take } | Call::decrease_take { hotkey, take } => { + if *take < Pallet::::get_min_delegate_take() { + return Err(Error::::DelegateTakeTooLow); + } + if *take > Pallet::::get_max_delegate_take() { + return Err(Error::::DelegateTakeTooHigh); + } + Pallet::::do_take_checks(who, hotkey) + } + _ => Ok(()), + } + } +} + +impl DispatchExtension> for CheckDelegateTake +where + T: Config, + CallOf: Dispatchable + IsSubType>, + DispatchableOriginOf: OriginTrait, +{ + type Pre = (); + + fn weight(_call: &CallOf) -> Weight { + ::WeightInfo::check_delegate_take_extension() + } + + fn pre_dispatch( + origin: &DispatchableOriginOf, + call: &CallOf, + ) -> Result { + let Some(who) = origin.as_signer() else { + return Ok(()); + }; + + let Some(call) = call.is_sub_type() else { + return Ok(()); + }; + + Self::check(who, call).map_err(Into::into) + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod tests { + use super::*; + use crate::{Error, tests::mock::*}; + use frame_support::{ + assert_ok, dispatch::DispatchResultWithPostInfo, traits::ExtendedDispatchable, + }; + use sp_core::U256; + use sp_runtime::DispatchError; + + fn increase_take_call(hotkey: U256, take: u16) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::increase_take { hotkey, take }) + } + + fn decrease_take_call(hotkey: U256, take: u16) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::decrease_take { hotkey, take }) + } + + fn dispatch_with_ext(call: RuntimeCall, origin: RuntimeOrigin) -> DispatchResultWithPostInfo { + as ExtendedDispatchable>::dispatch_with_extension( + origin, call, + ) + } + + fn err(result: DispatchResultWithPostInfo) -> DispatchError { + result.unwrap_err().error + } + + #[test] + fn accepts_owner_with_valid_take() { + new_test_ext(0).execute_with(|| { + let owner = U256::from(1); + let hotkey = U256::from(2); + crate::Owner::::insert(hotkey, owner); + + for call in [ + increase_take_call(hotkey, SubtensorModule::get_max_delegate_take()), + decrease_take_call(hotkey, SubtensorModule::get_min_delegate_take()), + ] { + assert_ok!(dispatch_with_ext(call, RuntimeOrigin::signed(owner))); + } + }); + } + + #[test] + fn rejects_take_too_low() { + new_test_ext(0).execute_with(|| { + let owner = U256::from(1); + let hotkey = U256::from(2); + crate::Owner::::insert(hotkey, owner); + + let take = SubtensorModule::get_min_delegate_take() - 1; + + for call in [ + increase_take_call(hotkey, take), + decrease_take_call(hotkey, take), + ] { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(owner))), + Error::::DelegateTakeTooLow.into() + ); + } + }); + } + + #[test] + fn rejects_take_too_high() { + new_test_ext(0).execute_with(|| { + let owner = U256::from(1); + let hotkey = U256::from(2); + crate::Owner::::insert(hotkey, owner); + + let take = SubtensorModule::get_max_delegate_take() + 1; + + for call in [ + increase_take_call(hotkey, take), + decrease_take_call(hotkey, take), + ] { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(owner))), + Error::::DelegateTakeTooHigh.into() + ); + } + }); + } + + #[test] + fn rejects_non_owner() { + new_test_ext(0).execute_with(|| { + let owner = U256::from(1); + let other = U256::from(2); + let hotkey = U256::from(3); + crate::Owner::::insert(hotkey, owner); + + let take = SubtensorModule::get_max_delegate_take(); + + for call in [ + increase_take_call(hotkey, take), + decrease_take_call(hotkey, take), + ] { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(other))), + Error::::NonAssociatedColdKey.into() + ); + } + }); + } + + #[test] + fn rejects_missing_hotkey_owner() { + new_test_ext(0).execute_with(|| { + let owner = U256::from(1); + let hotkey = U256::from(99); + let take = SubtensorModule::get_max_delegate_take(); + + for call in [ + increase_take_call(hotkey, take), + decrease_take_call(hotkey, take), + ] { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(owner))), + Error::::HotKeyAccountNotExists.into() + ); + } + }); + } +} diff --git a/pallets/subtensor/src/guards/check_evm_key_association.rs b/pallets/subtensor/src/guards/check_evm_key_association.rs new file mode 100644 index 0000000000..d7e2847e99 --- /dev/null +++ b/pallets/subtensor/src/guards/check_evm_key_association.rs @@ -0,0 +1,215 @@ +use crate::weights::WeightInfo; +use crate::{Call, Config, Error, Pallet}; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, DispatchExtension, DispatchInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::{IsSubType, OriginTrait}, +}; +use sp_runtime::traits::Dispatchable; +use sp_std::marker::PhantomData; + +type CallOf = ::RuntimeCall; +type DispatchableOriginOf = as Dispatchable>::RuntimeOrigin; + +/// Dispatch extension for EVM-key association preconditions. +/// +/// Signed EVM-key association calls are checked for subnet registration and +/// cooldown before dispatch; unrelated calls and non-signed origins pass through. +pub struct CheckEvmKeyAssociation(PhantomData); + +impl CheckEvmKeyAssociation { + pub fn check(who: &T::AccountId, call: &Call) -> Result<(), Error> { + match call { + Call::associate_evm_key { netuid, .. } => { + let uid = Pallet::::get_uid_for_net_and_hotkey(*netuid, who) + .map_err(|_| Error::::HotKeyNotRegisteredInSubNet)?; + Pallet::::ensure_evm_key_associate_rate_limit(*netuid, uid) + .map_err(|_| Error::::EvmKeyAssociateRateLimitExceeded)?; + Ok(()) + } + _ => Ok(()), + } + } +} + +impl DispatchExtension> for CheckEvmKeyAssociation +where + T: Config, + CallOf: Dispatchable + IsSubType>, + DispatchableOriginOf: OriginTrait, +{ + type Pre = (); + + fn weight(_call: &CallOf) -> Weight { + ::WeightInfo::check_evm_key_association_extension() + } + + fn pre_dispatch( + origin: &DispatchableOriginOf, + call: &CallOf, + ) -> Result { + let Some(who) = origin.as_signer() else { + return Ok(()); + }; + + let Some(call) = call.is_sub_type() else { + return Ok(()); + }; + + Self::check(who, call).map_err(Into::into) + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used, clippy::arithmetic_side_effects)] +mod tests { + use super::CheckEvmKeyAssociation; + use crate::{AssociatedEvmAddress, Error, tests::mock::*}; + use codec::Encode; + use frame_support::{ + assert_ok, dispatch::DispatchResultWithPostInfo, traits::ExtendedDispatchable, + }; + use frame_system::Call as SystemCall; + use sp_core::{H160, Pair, U256, ecdsa, keccak_256}; + use sp_runtime::DispatchError; + use subtensor_runtime_common::NetUid; + + fn dispatch_with_ext(call: RuntimeCall, origin: RuntimeOrigin) -> DispatchResultWithPostInfo { + as ExtendedDispatchable>::dispatch_with_extension( + origin, call, + ) + } + + fn err(result: DispatchResultWithPostInfo) -> DispatchError { + result.err().unwrap().error + } + + fn public_to_evm_key(pubkey: &ecdsa::Public) -> H160 { + let secp_pub = libsecp256k1::PublicKey::parse_compressed(&pubkey.0).unwrap(); + let uncompressed = secp_pub.serialize(); + let hash = keccak_256(&uncompressed[1..]); + H160::from_slice(&hash[12..]) + } + + fn sign_evm_message>(pair: &ecdsa::Pair, message: M) -> ecdsa::Signature { + let hash = SubtensorModule::hash_message_eip191(message); + let mut signature = pair.sign_prehashed(&hash); + signature.0[64] += 27; + signature + } + + fn associate_call( + netuid: NetUid, + evm_key: H160, + block_number: u64, + signature: ecdsa::Signature, + ) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::associate_evm_key { + netuid, + evm_key, + block_number, + signature, + }) + } + + fn dummy_associate_call(netuid: NetUid) -> RuntimeCall { + associate_call( + netuid, + H160::zero(), + 0, + ecdsa::Signature::from_raw([0_u8; 65]), + ) + } + + fn valid_associate_call(netuid: NetUid, hotkey: U256) -> (RuntimeCall, H160) { + let pair = ecdsa::Pair::generate().0; + let evm_key = public_to_evm_key(&pair.public()); + let block_number = System::block_number(); + let block_hash = keccak_256(block_number.encode().as_ref()); + let message = [ + hotkey.encode().as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&block_hash), + ] + .concat(); + let signature = sign_evm_message(&pair, message); + + ( + associate_call(netuid, evm_key, block_number, signature), + evm_key, + ) + } + + #[test] + fn unrelated_calls_pass_through() { + new_test_ext(0).execute_with(|| { + let hotkey = U256::from(1); + let call = RuntimeCall::System(SystemCall::remark { remark: vec![] }); + + assert_ok!(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))); + }); + } + + #[test] + fn registered_hotkey_allows_call() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + add_network(netuid, 1, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + System::set_block_number(EvmKeyAssociateRateLimit::get()); + + let (call, evm_key) = valid_associate_call(netuid, hotkey); + assert_ok!(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))); + + let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); + assert_eq!( + AssociatedEvmAddress::::get(netuid, uid), + Some((evm_key, SubtensorModule::get_current_block_as_u64())) + ); + }); + } + + #[test] + fn unregistered_hotkey_blocks_call() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + add_network(netuid, 1, 0); + + assert_eq!( + err(dispatch_with_ext( + dummy_associate_call(netuid), + RuntimeOrigin::signed(hotkey) + )), + Error::::HotKeyNotRegisteredInSubNet.into() + ); + }); + } + + #[test] + fn recent_association_blocks_call() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + add_network(netuid, 1, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); + System::set_block_number(300_u64); + AssociatedEvmAddress::::insert( + netuid, + uid, + (H160::zero(), SubtensorModule::get_current_block_as_u64()), + ); + + assert_eq!( + err(dispatch_with_ext( + dummy_associate_call(netuid), + RuntimeOrigin::signed(hotkey) + )), + Error::::EvmKeyAssociateRateLimitExceeded.into() + ); + }); + } +} diff --git a/pallets/subtensor/src/guards/check_rate_limits.rs b/pallets/subtensor/src/guards/check_rate_limits.rs new file mode 100644 index 0000000000..d2c021dd5d --- /dev/null +++ b/pallets/subtensor/src/guards/check_rate_limits.rs @@ -0,0 +1,251 @@ +use crate::weights::WeightInfo; +use crate::{Call, Config, Error, Pallet, TransactionType}; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, DispatchExtension, DispatchInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::{IsSubType, OriginTrait}, +}; +use sp_runtime::traits::Dispatchable; +use sp_std::marker::PhantomData; +use subtensor_runtime_common::{NetUid, NetUidStorageIndex}; + +type CallOf = ::RuntimeCall; +type DispatchableOriginOf = as Dispatchable>::RuntimeOrigin; + +/// Dispatch extension for rate-limit checks that are safe to reject before dispatch. +/// +/// Signed weight and network-registration calls are checked before dispatch; +/// unrelated calls and non-signed origins pass through. +pub struct CheckRateLimits(PhantomData); + +impl CheckRateLimits { + fn check_weights_rate_limit( + who: &T::AccountId, + netuid: NetUid, + netuid_index: NetUidStorageIndex, + error: Error, + ) -> Result<(), Error> { + let Ok(neuron_uid) = Pallet::::get_uid_for_net_and_hotkey(netuid, who) else { + return Ok(()); + }; + + let current_block = Pallet::::get_current_block_as_u64(); + if Pallet::::check_rate_limit(netuid_index, neuron_uid, current_block) { + Ok(()) + } else { + Err(error) + } + } + + pub fn check(who: &T::AccountId, call: &Call) -> Result<(), Error> { + match call { + Call::commit_weights { netuid, .. } => Self::check_weights_rate_limit( + who, + *netuid, + NetUidStorageIndex::from(*netuid), + Error::::CommittingWeightsTooFast, + ), + Call::commit_mechanism_weights { netuid, mecid, .. } => Self::check_weights_rate_limit( + who, + *netuid, + Pallet::::get_mechanism_storage_index(*netuid, *mecid), + Error::::CommittingWeightsTooFast, + ), + Call::set_weights { netuid, .. } + if !Pallet::::get_commit_reveal_weights_enabled(*netuid) => + { + Self::check_weights_rate_limit( + who, + *netuid, + NetUidStorageIndex::from(*netuid), + Error::::SettingWeightsTooFast, + ) + } + Call::set_mechanism_weights { netuid, mecid, .. } + if !Pallet::::get_commit_reveal_weights_enabled(*netuid) => + { + Self::check_weights_rate_limit( + who, + *netuid, + Pallet::::get_mechanism_storage_index(*netuid, *mecid), + Error::::SettingWeightsTooFast, + ) + } + Call::register_network { .. } + if !TransactionType::RegisterNetwork.passes_rate_limit::(who) => + { + Err(Error::::NetworkTxRateLimitExceeded) + } + _ => Ok(()), + } + } +} + +impl DispatchExtension> for CheckRateLimits +where + T: Config, + CallOf: Dispatchable + IsSubType>, + DispatchableOriginOf: OriginTrait, +{ + type Pre = (); + + fn weight(_call: &CallOf) -> Weight { + ::WeightInfo::check_rate_limits_extension() + } + + fn pre_dispatch( + origin: &DispatchableOriginOf, + call: &CallOf, + ) -> Result { + let Some(who) = origin.as_signer() else { + return Ok(()); + }; + + let Some(call) = call.is_sub_type() else { + return Ok(()); + }; + + Self::check(who, call).map_err(Into::into) + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod tests { + use super::CheckRateLimits; + use crate::{Error, tests::mock::*}; + use frame_support::{ + assert_ok, dispatch::DispatchResultWithPostInfo, traits::ExtendedDispatchable, + }; + use frame_system::Call as SystemCall; + use sp_core::U256; + use sp_runtime::DispatchError; + use subtensor_runtime_common::{MechId, NetUid, TaoBalance}; + + fn dispatch_with_ext(call: RuntimeCall, origin: RuntimeOrigin) -> DispatchResultWithPostInfo { + as ExtendedDispatchable>::dispatch_with_extension( + origin, call, + ) + } + + fn err(result: DispatchResultWithPostInfo) -> DispatchError { + result.err().unwrap().error + } + + fn register_neuron(netuid: NetUid, hotkey: U256, coldkey: U256) { + add_network(netuid, 1, 0); + setup_reserves(netuid, DEFAULT_RESERVE.into(), DEFAULT_RESERVE.into()); + register_ok_neuron(netuid, hotkey, coldkey, 0); + } + + fn set_weights_call(netuid: NetUid, uid: u16) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::set_weights { + netuid, + dests: vec![uid], + weights: vec![1], + version_key: 0, + }) + } + + fn register_network_call(hotkey: U256) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::register_network { hotkey }) + } + + fn fund(coldkey: U256, amount: TaoBalance) { + add_balance_to_coldkey_account(&coldkey, amount); + } + + #[test] + fn unrelated_calls_pass_through() { + new_test_ext(0).execute_with(|| { + let call = RuntimeCall::System(SystemCall::remark { remark: vec![] }); + + assert_ok!(dispatch_with_ext( + call, + RuntimeOrigin::signed(U256::from(1)) + )); + }); + } + + #[test] + fn over_rate_set_weights_is_blocked() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + register_neuron(netuid, hotkey, coldkey); + SubtensorModule::set_commit_reveal_weights_enabled(netuid, false); + SubtensorModule::set_weights_set_rate_limit(netuid, 100); + System::set_block_number(10_u64); + let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); + let netuid_index = SubtensorModule::get_mechanism_storage_index(netuid, MechId::MAIN); + SubtensorModule::set_last_update_for_uid( + netuid_index, + uid, + SubtensorModule::get_current_block_as_u64(), + ); + + assert_eq!( + err(dispatch_with_ext( + set_weights_call(netuid, uid), + RuntimeOrigin::signed(hotkey) + )), + Error::::SettingWeightsTooFast.into() + ); + }); + } + + #[test] + fn set_weights_within_rate_limit_dispatches() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + register_neuron(netuid, hotkey, coldkey); + SubtensorModule::set_commit_reveal_weights_enabled(netuid, false); + SubtensorModule::set_weights_set_rate_limit(netuid, 100); + SubtensorModule::set_stake_threshold(0); + System::set_block_number(200_u64); + let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); + + assert_ok!(dispatch_with_ext( + set_weights_call(netuid, uid), + RuntimeOrigin::signed(hotkey) + )); + }); + } + + #[test] + fn over_rate_network_registration_is_blocked() { + new_test_ext(0).execute_with(|| { + crate::NetworkRateLimit::::put(50_u64); + System::set_block_number(200_u64); + SubtensorModule::set_network_last_lock_block(170); + let coldkey = U256::from(70); + + assert_eq!( + err(dispatch_with_ext( + register_network_call(U256::from(71)), + RuntimeOrigin::signed(coldkey) + )), + Error::::NetworkTxRateLimitExceeded.into() + ); + }); + } + + #[test] + fn network_registration_after_rate_limit_dispatches() { + new_test_ext(0).execute_with(|| { + crate::NetworkRateLimit::::put(50_u64); + System::set_block_number(200_u64); + SubtensorModule::set_network_last_lock_block(100); + let coldkey = U256::from(70); + fund(coldkey, SubtensorModule::get_network_lock_cost().into()); + + assert_ok!(dispatch_with_ext( + register_network_call(U256::from(71)), + RuntimeOrigin::signed(coldkey) + )); + }); + } +} diff --git a/pallets/subtensor/src/guards/check_serving_endpoints.rs b/pallets/subtensor/src/guards/check_serving_endpoints.rs new file mode 100644 index 0000000000..46304d337f --- /dev/null +++ b/pallets/subtensor/src/guards/check_serving_endpoints.rs @@ -0,0 +1,218 @@ +use crate::weights::WeightInfo; +use crate::{Call, Config, Error, Pallet}; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, DispatchExtension, DispatchInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::{IsSubType, OriginTrait}, +}; +use sp_runtime::traits::Dispatchable; +use sp_std::marker::PhantomData; + +type CallOf = ::RuntimeCall; +type DispatchableOriginOf = as Dispatchable>::RuntimeOrigin; + +/// Dispatch extension for axon/prometheus endpoint validation. +/// +/// Signed serving calls are checked before dispatch; unrelated calls and +/// non-signed origins pass through. +pub struct CheckServingEndpoints(PhantomData); + +impl CheckServingEndpoints { + pub fn check(who: &T::AccountId, call: &Call) -> Result<(), Error> { + match call { + Call::serve_axon { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + } + | Call::serve_axon_tls { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + .. + } => Pallet::::validate_serve_axon( + who, + *netuid, + *version, + *ip, + *port, + *ip_type, + *protocol, + *placeholder1, + *placeholder2, + ), + Call::serve_prometheus { + netuid, + version, + ip, + port, + ip_type, + } => { + Pallet::::validate_serve_prometheus(who, *netuid, *version, *ip, *port, *ip_type) + .map(|_| ()) + } + _ => Ok(()), + } + } +} + +impl DispatchExtension> for CheckServingEndpoints +where + T: Config, + CallOf: Dispatchable + IsSubType>, + DispatchableOriginOf: OriginTrait, +{ + type Pre = (); + + fn weight(_call: &CallOf) -> Weight { + ::WeightInfo::check_serving_endpoints_extension() + } + + fn pre_dispatch( + origin: &DispatchableOriginOf, + call: &CallOf, + ) -> Result { + let Some(who) = origin.as_signer() else { + return Ok(()); + }; + + let Some(call) = call.is_sub_type() else { + return Ok(()); + }; + + Self::check(who, call).map_err(Into::into) + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod tests { + use super::CheckServingEndpoints; + use crate::{Error, tests::mock::*}; + use frame_support::{ + assert_ok, dispatch::DispatchResultWithPostInfo, traits::ExtendedDispatchable, + }; + use frame_system::Call as SystemCall; + use sp_core::U256; + use sp_runtime::DispatchError; + use subtensor_runtime_common::NetUid; + + fn dispatch_with_ext(call: RuntimeCall, origin: RuntimeOrigin) -> DispatchResultWithPostInfo { + as ExtendedDispatchable>::dispatch_with_extension( + origin, call, + ) + } + + fn err(result: DispatchResultWithPostInfo) -> DispatchError { + result.err().unwrap().error + } + + fn serve_axon_call(netuid: NetUid) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::serve_axon { + netuid, + version: 1, + ip: u128::from(u32::from_be_bytes([8, 8, 8, 8])), + port: 1, + ip_type: 4, + protocol: 0, + placeholder1: 0, + placeholder2: 0, + }) + } + + fn serve_axon_tls_call(netuid: NetUid) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::serve_axon_tls { + netuid, + version: 1, + ip: u128::from(u32::from_be_bytes([8, 8, 8, 8])), + port: 1, + ip_type: 4, + protocol: 0, + placeholder1: 0, + placeholder2: 0, + certificate: vec![], + }) + } + + fn serve_prometheus_call(netuid: NetUid) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::serve_prometheus { + netuid, + version: 1, + ip: u128::from(u32::from_be_bytes([8, 8, 4, 4])), + port: 1, + ip_type: 4, + }) + } + + fn register_hotkey(netuid: NetUid, hotkey: U256, coldkey: U256) { + add_network(netuid, 1, 0); + setup_reserves(netuid, DEFAULT_RESERVE.into(), DEFAULT_RESERVE.into()); + register_ok_neuron(netuid, hotkey, coldkey, 0); + } + + #[test] + fn unrelated_calls_pass_through() { + new_test_ext(0).execute_with(|| { + let call = RuntimeCall::System(SystemCall::remark { remark: vec![] }); + + assert_ok!(dispatch_with_ext( + call, + RuntimeOrigin::signed(U256::from(1)) + )); + }); + } + + #[test] + fn unregistered_hotkey_blocks_axon() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let calls = [serve_axon_call(netuid), serve_axon_tls_call(netuid)]; + + for call in calls { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))), + Error::::HotKeyNotRegisteredInNetwork.into() + ); + } + }); + } + + #[test] + fn registered_hotkey_allows_axon() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + register_hotkey(netuid, hotkey, U256::from(2)); + let calls = [serve_axon_call(netuid), serve_axon_tls_call(netuid)]; + + for call in calls { + assert_ok!(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))); + } + }); + } + + #[test] + fn registered_hotkey_allows_prometheus() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + register_hotkey(netuid, hotkey, U256::from(2)); + + assert_ok!(dispatch_with_ext( + serve_prometheus_call(netuid), + RuntimeOrigin::signed(hotkey) + )); + }); + } +} diff --git a/pallets/subtensor/src/guards/check_weights.rs b/pallets/subtensor/src/guards/check_weights.rs new file mode 100644 index 0000000000..d10e7b8b8c --- /dev/null +++ b/pallets/subtensor/src/guards/check_weights.rs @@ -0,0 +1,613 @@ +use crate::weights::WeightInfo; +use crate::{Call, Config, Error, Pallet, WeightCommits}; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, DispatchExtension, DispatchInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::{IsSubType, OriginTrait}, +}; +use sp_core::H256; +use sp_runtime::traits::Dispatchable; +use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, vec::Vec}; +use subtensor_runtime_common::{NetUid, NetUidStorageIndex}; + +type CallOf = ::RuntimeCall; +type DispatchableOriginOf = as Dispatchable>::RuntimeOrigin; +type WeightCommitQueue = VecDeque<(H256, u64, u64, u64)>; + +/// Dispatch extension for weight-setting preconditions. +/// +/// Signed weight calls are checked for batch shape, min stake, and commit/reveal +/// prerequisites before dispatch; unrelated calls and non-signed origins pass through. +pub struct CheckWeights(PhantomData); + +impl CheckWeights { + pub fn check(who: &T::AccountId, call: &Call) -> Result<(), Error> { + Self::check_input_lengths(call)?; + Self::check_min_stake(who, call)?; + Self::check_commit_reveal(who, call) + } + + fn check_input_lengths(call: &Call) -> Result<(), Error> { + let lengths_match = match call { + Call::batch_commit_weights { + netuids, + commit_hashes, + } => netuids.len() == commit_hashes.len(), + Call::batch_reveal_weights { + uids_list, + values_list, + salts_list, + version_keys, + .. + } => { + uids_list.len() == values_list.len() + && uids_list.len() == salts_list.len() + && uids_list.len() == version_keys.len() + } + Call::batch_set_weights { + netuids, + weights, + version_keys, + } => netuids.len() == weights.len() && netuids.len() == version_keys.len(), + _ => true, + }; + + if lengths_match { + Ok(()) + } else { + Err(Error::::InputLengthsUnequal) + } + } + + fn ensure_min_stake(who: &T::AccountId, netuid: NetUid) -> Result<(), Error> { + if Pallet::::check_weights_min_stake(who, netuid) { + Ok(()) + } else { + Err(Error::::NotEnoughStakeToSetWeights) + } + } + + fn check_min_stake(who: &T::AccountId, call: &Call) -> Result<(), Error> { + match call { + Call::commit_weights { netuid, .. } + | Call::commit_mechanism_weights { netuid, .. } + | Call::reveal_weights { netuid, .. } + | Call::reveal_mechanism_weights { netuid, .. } + | Call::batch_reveal_weights { netuid, .. } + | Call::set_weights { netuid, .. } + | Call::set_mechanism_weights { netuid, .. } + | Call::commit_timelocked_weights { netuid, .. } + | Call::commit_timelocked_mechanism_weights { netuid, .. } + | Call::commit_crv3_mechanism_weights { netuid, .. } => { + Self::ensure_min_stake(who, *netuid) + } + Call::batch_commit_weights { netuids, .. } + | Call::batch_set_weights { netuids, .. } => { + for netuid in netuids.iter() { + Self::ensure_min_stake(who, (*netuid).into())?; + } + Ok(()) + } + _ => Ok(()), + } + } + + fn find_commit_epoch(commits: &WeightCommitQueue, hash: H256) -> Option { + commits + .iter() + .find_map(|(commit_hash, commit_epoch, _, _)| { + (*commit_hash == hash).then_some(*commit_epoch) + }) + } + + fn check_reveal( + who: &T::AccountId, + netuid: NetUid, + netuid_index: NetUidStorageIndex, + uids: &[u16], + values: &[u16], + salt: &[u16], + version_key: u64, + ) -> Result<(), Error> { + let commits = + WeightCommits::::get(netuid_index, who).ok_or(Error::::NoWeightsCommitFound)?; + let hash = Pallet::::get_commit_hash(who, netuid_index, uids, values, salt, version_key); + let commit_epoch = + Self::find_commit_epoch(&commits, hash).ok_or(Error::::NoWeightsCommitFound)?; + + if Pallet::::is_reveal_block_range(netuid, commit_epoch) { + Ok(()) + } else { + Err(Error::::RevealTooEarly) + } + } + + fn check_batch_reveal( + who: &T::AccountId, + netuid: NetUid, + uids_list: &[Vec], + values_list: &[Vec], + salts_list: &[Vec], + version_keys: &[u64], + ) -> Result<(), Error> { + if uids_list.len() != values_list.len() + || uids_list.len() != salts_list.len() + || uids_list.len() != version_keys.len() + { + return Err(Error::::InputLengthsUnequal); + } + + let netuid_index = NetUidStorageIndex::from(netuid); + let commits = + WeightCommits::::get(netuid_index, who).ok_or(Error::::NoWeightsCommitFound)?; + + for (((uids, values), salt), version_key) in uids_list + .iter() + .zip(values_list) + .zip(salts_list) + .zip(version_keys) + { + let hash = + Pallet::::get_commit_hash(who, netuid_index, uids, values, salt, *version_key); + let commit_epoch = + Self::find_commit_epoch(&commits, hash).ok_or(Error::::NoWeightsCommitFound)?; + + if !Pallet::::is_reveal_block_range(netuid, commit_epoch) { + return Err(Error::::RevealTooEarly); + } + } + + Ok(()) + } + + fn check_commit_reveal(who: &T::AccountId, call: &Call) -> Result<(), Error> { + match call { + Call::reveal_weights { + netuid, + uids, + values, + salt, + version_key, + } => Self::check_reveal( + who, + *netuid, + NetUidStorageIndex::from(*netuid), + uids, + values, + salt, + *version_key, + ), + Call::reveal_mechanism_weights { + netuid, + mecid, + uids, + values, + salt, + version_key, + } => Self::check_reveal( + who, + *netuid, + Pallet::::get_mechanism_storage_index(*netuid, *mecid), + uids, + values, + salt, + *version_key, + ), + Call::batch_reveal_weights { + netuid, + uids_list, + values_list, + salts_list, + version_keys, + } => Self::check_batch_reveal( + who, + *netuid, + uids_list, + values_list, + salts_list, + version_keys, + ), + Call::commit_timelocked_weights { reveal_round, .. } + | Call::commit_timelocked_mechanism_weights { reveal_round, .. } + | Call::commit_crv3_mechanism_weights { reveal_round, .. } + if *reveal_round < pallet_drand::LastStoredRound::::get() => + { + Err(Error::::InvalidRevealRound) + } + _ => Ok(()), + } + } +} + +impl DispatchExtension> for CheckWeights +where + T: Config, + CallOf: Dispatchable + IsSubType>, + DispatchableOriginOf: OriginTrait, +{ + type Pre = (); + + fn weight(_call: &CallOf) -> Weight { + ::WeightInfo::check_weights_extension() + } + + fn pre_dispatch( + origin: &DispatchableOriginOf, + call: &CallOf, + ) -> Result { + let Some(who) = origin.as_signer() else { + return Ok(()); + }; + + let Some(call) = call.is_sub_type() else { + return Ok(()); + }; + + Self::check(who, call).map_err(Into::into) + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod tests { + use super::CheckWeights; + use crate::{Error, MAX_CRV3_COMMIT_SIZE_BYTES, tests::mock::*}; + use codec::Compact; + use frame_support::{ + BoundedVec, assert_ok, dispatch::DispatchResultWithPostInfo, traits::ConstU32, + traits::ExtendedDispatchable, + }; + use frame_system::Call as SystemCall; + use pallet_drand::LastStoredRound; + use sp_core::{H256, U256}; + use sp_runtime::DispatchError; + use subtensor_runtime_common::{MechId, NetUid}; + + fn dispatch_with_ext(call: RuntimeCall, origin: RuntimeOrigin) -> DispatchResultWithPostInfo { + as ExtendedDispatchable>::dispatch_with_extension( + origin, call, + ) + } + + fn err(result: DispatchResultWithPostInfo) -> DispatchError { + result.err().unwrap().error + } + + fn register_neuron(netuid: NetUid, hotkey: U256, coldkey: U256) { + add_network(netuid, 1, 0); + setup_reserves(netuid, DEFAULT_RESERVE.into(), DEFAULT_RESERVE.into()); + register_ok_neuron(netuid, hotkey, coldkey, 0); + } + + fn set_weights_call(netuid: NetUid, uid: u16) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::set_weights { + netuid, + dests: vec![uid], + weights: vec![1], + version_key: 0, + }) + } + + fn reveal_weights_call(netuid: NetUid) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::reveal_weights { + netuid, + uids: vec![0], + values: vec![1], + salt: vec![1], + version_key: 0, + }) + } + + fn reveal_mechanism_weights_call(netuid: NetUid, mecid: MechId) -> RuntimeCall { + RuntimeCall::SubtensorModule(SubtensorCall::reveal_mechanism_weights { + netuid, + mecid, + uids: vec![0], + values: vec![1], + salt: vec![1], + version_key: 0, + }) + } + + #[test] + fn unrelated_calls_pass_through() { + new_test_ext(0).execute_with(|| { + let call = RuntimeCall::System(SystemCall::remark { remark: vec![] }); + + assert_ok!(dispatch_with_ext( + call, + RuntimeOrigin::signed(U256::from(1)) + )); + }); + } + + #[test] + fn mismatched_batch_lengths_are_blocked() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let calls = [ + RuntimeCall::SubtensorModule(SubtensorCall::batch_commit_weights { + netuids: vec![Compact(netuid)], + commit_hashes: vec![], + }), + RuntimeCall::SubtensorModule(SubtensorCall::batch_reveal_weights { + netuid, + uids_list: vec![vec![0]], + values_list: vec![], + salts_list: vec![vec![1]], + version_keys: vec![0], + }), + RuntimeCall::SubtensorModule(SubtensorCall::batch_set_weights { + netuids: vec![Compact(netuid)], + weights: vec![], + version_keys: vec![Compact(0_u64)], + }), + ]; + + for call in calls { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))), + Error::::InputLengthsUnequal.into() + ); + } + }); + } + + #[test] + fn low_stake_weight_calls_are_blocked() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + let bounded_commit = + BoundedVec::>::try_from(vec![0]).unwrap(); + add_network_disable_commit_reveal(netuid, 1, 0); + setup_reserves(netuid, DEFAULT_RESERVE.into(), DEFAULT_RESERVE.into()); + SubtensorModule::append_neuron(netuid, &hotkey, 0); + crate::Owner::::insert(hotkey, coldkey); + SubtensorModule::set_stake_threshold(1_000_000_000_000_u64); + + let calls = [ + set_weights_call(netuid, 0), + RuntimeCall::SubtensorModule(SubtensorCall::set_mechanism_weights { + netuid, + mecid: MechId::MAIN, + dests: vec![0], + weights: vec![1], + version_key: 0, + }), + RuntimeCall::SubtensorModule(SubtensorCall::batch_set_weights { + netuids: vec![Compact(netuid)], + weights: vec![vec![(Compact(0_u16), Compact(1_u16))]], + version_keys: vec![Compact(0_u64)], + }), + RuntimeCall::SubtensorModule(SubtensorCall::commit_weights { + netuid, + commit_hash: H256::zero(), + }), + RuntimeCall::SubtensorModule(SubtensorCall::commit_mechanism_weights { + netuid, + mecid: MechId::MAIN, + commit_hash: H256::zero(), + }), + RuntimeCall::SubtensorModule(SubtensorCall::batch_commit_weights { + netuids: vec![Compact(netuid)], + commit_hashes: vec![H256::zero()], + }), + reveal_weights_call(netuid), + reveal_mechanism_weights_call(netuid, MechId::MAIN), + RuntimeCall::SubtensorModule(SubtensorCall::batch_reveal_weights { + netuid, + uids_list: vec![vec![0]], + values_list: vec![vec![1]], + salts_list: vec![vec![1]], + version_keys: vec![0], + }), + RuntimeCall::SubtensorModule(SubtensorCall::commit_timelocked_weights { + netuid, + commit: bounded_commit.clone(), + reveal_round: 0, + commit_reveal_version: 0, + }), + RuntimeCall::SubtensorModule(SubtensorCall::commit_timelocked_mechanism_weights { + netuid, + mecid: MechId::MAIN, + commit: bounded_commit.clone(), + reveal_round: 0, + commit_reveal_version: 0, + }), + RuntimeCall::SubtensorModule(SubtensorCall::commit_crv3_mechanism_weights { + netuid, + mecid: MechId::MAIN, + commit: bounded_commit, + reveal_round: 0, + }), + ]; + + for call in calls { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))), + Error::::NotEnoughStakeToSetWeights.into() + ); + } + }); + } + + #[test] + fn valid_set_weights_call_dispatches() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + add_network_disable_commit_reveal(netuid, 1, 0); + setup_reserves(netuid, DEFAULT_RESERVE.into(), DEFAULT_RESERVE.into()); + register_ok_neuron(netuid, hotkey, coldkey, 0); + SubtensorModule::set_stake_threshold(0); + let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); + + assert_ok!(dispatch_with_ext( + set_weights_call(netuid, uid), + RuntimeOrigin::signed(hotkey) + )); + }); + } + + #[test] + fn missing_commit_is_blocked() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + register_neuron(netuid, hotkey, coldkey); + SubtensorModule::set_stake_threshold(0); + let calls = [ + reveal_weights_call(netuid), + reveal_mechanism_weights_call(netuid, MechId::MAIN), + RuntimeCall::SubtensorModule(SubtensorCall::batch_reveal_weights { + netuid, + uids_list: vec![vec![0]], + values_list: vec![vec![1]], + salts_list: vec![vec![1]], + version_keys: vec![0], + }), + ]; + + for call in calls { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))), + Error::::NoWeightsCommitFound.into() + ); + } + }); + } + + #[test] + fn reveal_before_window_is_blocked() { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + let uids = vec![0]; + let values = vec![1]; + let salt = vec![1]; + let version_key = 0; + register_neuron(netuid, hotkey, coldkey); + SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::set_stake_threshold(0); + let commit_hash = SubtensorModule::get_commit_hash( + &hotkey, + netuid.into(), + &uids, + &values, + &salt, + version_key, + ); + assert_ok!(SubtensorModule::commit_weights( + RuntimeOrigin::signed(hotkey), + netuid, + commit_hash, + )); + + assert_eq!( + err(dispatch_with_ext( + reveal_weights_call(netuid), + RuntimeOrigin::signed(hotkey) + )), + Error::::RevealTooEarly.into() + ); + }); + } + + #[test] + fn valid_mechanism_reveal_dispatches() { + for (mecid, mechanism_count) in [ + (MechId::MAIN, None), + (MechId::from(1_u8), Some(MechId::from(2_u8))), + ] { + new_test_ext(0).execute_with(|| { + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + let uids = vec![0]; + let values = vec![1]; + let salt = vec![1]; + let version_key = 0; + register_neuron(netuid, hotkey, coldkey); + if let Some(mechanism_count) = mechanism_count { + crate::MechanismCountCurrent::::insert(netuid, mechanism_count); + } + SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::set_stake_threshold(0); + + let commit_hash = SubtensorModule::get_commit_hash( + &hotkey, + SubtensorModule::get_mechanism_storage_index(netuid, mecid), + &uids, + &values, + &salt, + version_key, + ); + assert_ok!(SubtensorModule::commit_mechanism_weights( + RuntimeOrigin::signed(hotkey), + netuid, + mecid, + commit_hash, + )); + step_epochs(1, netuid); + + let call = RuntimeCall::SubtensorModule(SubtensorCall::reveal_mechanism_weights { + netuid, + mecid, + uids, + values, + salt, + version_key, + }); + assert_ok!(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))); + }); + } + } + + #[test] + fn invalid_reveal_round_is_blocked() { + new_test_ext(0).execute_with(|| { + LastStoredRound::::put(1_000_u64); + let netuid = NetUid::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + register_neuron(netuid, hotkey, coldkey); + SubtensorModule::set_stake_threshold(0); + let commit = + BoundedVec::>::try_from(vec![0]).unwrap(); + let calls = [ + RuntimeCall::SubtensorModule(SubtensorCall::commit_timelocked_weights { + netuid, + commit: commit.clone(), + reveal_round: 999, + commit_reveal_version: 0, + }), + RuntimeCall::SubtensorModule(SubtensorCall::commit_timelocked_mechanism_weights { + netuid, + mecid: MechId::MAIN, + commit: commit.clone(), + reveal_round: 999, + commit_reveal_version: 0, + }), + RuntimeCall::SubtensorModule(SubtensorCall::commit_crv3_mechanism_weights { + netuid, + mecid: MechId::MAIN, + commit, + reveal_round: 999, + }), + ]; + + for call in calls { + assert_eq!( + err(dispatch_with_ext(call, RuntimeOrigin::signed(hotkey))), + Error::::InvalidRevealRound.into() + ); + } + }); + } +} diff --git a/pallets/subtensor/src/guards/mod.rs b/pallets/subtensor/src/guards/mod.rs index 44fba0c50f..485fc65a04 100644 --- a/pallets/subtensor/src/guards/mod.rs +++ b/pallets/subtensor/src/guards/mod.rs @@ -1,3 +1,13 @@ mod check_coldkey_swap; +mod check_delegate_take; +mod check_evm_key_association; +mod check_rate_limits; +mod check_serving_endpoints; +mod check_weights; pub use check_coldkey_swap::*; +pub use check_delegate_take::*; +pub use check_evm_key_association::*; +pub use check_rate_limits::*; +pub use check_serving_endpoints::*; +pub use check_weights::*; diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 410e3bef16..1ad77779f5 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -17,8 +17,6 @@ use frame_support::{ pallet_prelude::*, traits::tokens::fungible, }; -use pallet_balances::Call as BalancesCall; -// use pallet_scheduler as Scheduler; use scale_info::TypeInfo; use sp_core::Get; use sp_runtime::DispatchError; diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 7f5b119d31..32e0fbcbd6 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -243,6 +243,8 @@ mod errors { SymbolAlreadyInUse, /// Incorrect commit-reveal version. IncorrectCommitRevealVersion, + /// Reveal round is older than the most recently stored DRAND round. + InvalidRevealRound, /// Reveal period is too large. RevealPeriodTooLarge, /// Reveal period is too small. diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index 5416e3df5d..585fc897c0 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -297,9 +297,9 @@ impl Pallet { placeholder1: u8, placeholder2: u8, ) -> Result<(), Error> { - // Ensure the hotkey is registered somewhere. + // Ensure the hotkey is registered on the subnet it is serving. ensure!( - Self::is_hotkey_registered_on_any_network(hotkey_id), + Self::is_hotkey_registered_on_network(netuid, hotkey_id), Error::::HotKeyNotRegisteredInNetwork ); @@ -354,7 +354,7 @@ impl Pallet { ); ensure!( - Self::is_hotkey_registered_on_any_network(hotkey_id), + Self::is_hotkey_registered_on_network(netuid, hotkey_id), Error::::HotKeyNotRegisteredInNetwork ); diff --git a/pallets/subtensor/src/tests/mock.rs b/pallets/subtensor/src/tests/mock.rs index 49ec0c1638..83391cfbbb 100644 --- a/pallets/subtensor/src/tests/mock.rs +++ b/pallets/subtensor/src/tests/mock.rs @@ -157,7 +157,14 @@ impl system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; - type DispatchExtension = crate::CheckColdkeySwap; + type DispatchExtension = ( + crate::CheckColdkeySwap, + crate::CheckWeights, + crate::CheckRateLimits, + crate::CheckDelegateTake, + crate::CheckServingEndpoints, + crate::CheckEvmKeyAssociation, + ); } parameter_types! { diff --git a/pallets/subtensor/src/tests/mock_high_ed.rs b/pallets/subtensor/src/tests/mock_high_ed.rs index cb381a3f81..3d332e04fa 100644 --- a/pallets/subtensor/src/tests/mock_high_ed.rs +++ b/pallets/subtensor/src/tests/mock_high_ed.rs @@ -117,7 +117,14 @@ impl system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; - type DispatchExtension = crate::CheckColdkeySwap; + type DispatchExtension = ( + crate::CheckColdkeySwap, + crate::CheckWeights, + crate::CheckRateLimits, + crate::CheckDelegateTake, + crate::CheckServingEndpoints, + crate::CheckEvmKeyAssociation, + ); } parameter_types! { diff --git a/pallets/subtensor/src/tests/mod.rs b/pallets/subtensor/src/tests/mod.rs index c6444c3b9e..2a9f71e021 100644 --- a/pallets/subtensor/src/tests/mod.rs +++ b/pallets/subtensor/src/tests/mod.rs @@ -33,7 +33,6 @@ mod swap_hotkey; mod swap_hotkey_with_subnet; mod tao; mod tempo_control; -mod transaction_extension_pays_no; mod uids; mod voting_power; mod weights; diff --git a/pallets/subtensor/src/tests/serving.rs b/pallets/subtensor/src/tests/serving.rs index 2979d4438c..f63dcd5f81 100644 --- a/pallets/subtensor/src/tests/serving.rs +++ b/pallets/subtensor/src/tests/serving.rs @@ -2,17 +2,14 @@ use super::mock::*; use crate::Error; -use crate::extensions::SubtensorTransactionExtension; use crate::*; use frame_support::assert_noop; use frame_support::{ assert_ok, dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}, }; -use frame_system::{Config, RawOrigin}; +use frame_system::Config; use sp_core::U256; -use sp_runtime::traits::{DispatchInfoOf, TransactionExtension, TxBaseImplication}; -use subtensor_runtime_common::CustomTransactionError; mod test { use std::net::{Ipv4Addr, Ipv6Addr}; @@ -1171,74 +1168,3 @@ fn test_set_subnet_identity_dispatch_info_ok() { assert_eq!(dispatch_info.pays_fee, Pays::Yes); }); } - -// cargo test --package pallet-subtensor --lib -- tests::serving::test_serve_axon_validate --exact --show-output -#[test] -fn test_serve_axon_validate() { - // Testing the signed extension validate function - // correctly filters the `serve_axon` transaction. - - new_test_ext(0).execute_with(|| { - let hotkey = U256::from(1); - let netuid = NetUid::from(1); - let version: u32 = 2; - let ip: u128 = 1676056785; - let port: u16 = 128; - let ip_type: u8 = 4; - let protocol: u8 = 0; - let placeholder1: u8 = 0; - let placeholder2: u8 = 0; - - // Serve axon bad call - let call = RuntimeCall::SubtensorModule(SubtensorCall::serve_axon { - netuid, - version, - ip, - port, - ip_type, - protocol, - placeholder1, - placeholder2, - }); - - let info: DispatchInfo = - DispatchInfoOf::<::RuntimeCall>::default(); - - let extension = SubtensorTransactionExtension::::new(); - // Submit to the signed extension validate function - let result_bad = extension.validate( - RawOrigin::Signed(hotkey).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - - // Should fail due to insufficient stake - assert_eq!( - result_bad.unwrap_err(), - CustomTransactionError::HotKeyNotRegisteredInNetwork.into() - ); - - // Register the hotkey in the subnet and try again - let coldkey = U256::from(1); - add_network(netuid, 13, 0); - register_ok_neuron(netuid, hotkey, coldkey, 0); - - // Submit to the signed extension validate function - let result_ok = extension.validate( - RawOrigin::Signed(hotkey).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - - // Now the call passes - assert_ok!(result_ok); - }); -} diff --git a/pallets/subtensor/src/tests/transaction_extension_pays_no.rs b/pallets/subtensor/src/tests/transaction_extension_pays_no.rs deleted file mode 100644 index cea918ddd9..0000000000 --- a/pallets/subtensor/src/tests/transaction_extension_pays_no.rs +++ /dev/null @@ -1,773 +0,0 @@ -//! Transaction extension coverage for extrinsics handled by [`crate::extensions::SubtensorTransactionExtension`]. - -#![allow(clippy::unwrap_used)] - -use super::mock::*; -use crate::extensions::SubtensorTransactionExtension; -use crate::*; -use codec::Compact; -use frame_support::dispatch::GetDispatchInfo; -use frame_support::{BoundedVec, assert_ok, traits::ConstU32}; -use frame_system::RawOrigin; -use pallet_drand::LastStoredRound; -use sp_core::H256; -use sp_core::U256; -use sp_runtime::traits::{DispatchInfoOf, TransactionExtension, TxBaseImplication}; -use sp_runtime::transaction_validity::{TransactionSource, TransactionValidityError}; -use subtensor_runtime_common::{CustomTransactionError, MechId, NetUid, TaoBalance}; - -fn dispatch_info() -> sp_runtime::traits::DispatchInfoOf<::RuntimeCall> -{ - DispatchInfoOf::<::RuntimeCall>::default() -} - -fn validate_signed( - signer: U256, - call: &RuntimeCall, -) -> Result { - SubtensorTransactionExtension::::new() - .validate( - RawOrigin::Signed(signer).into(), - call, - &dispatch_info(), - 0, - (), - &TxBaseImplication(()), - TransactionSource::External, - ) - .map(|(v, _, _)| v) -} - -#[test] -fn extension_set_weights_rejects_stake_too_low() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network_disable_commit_reveal(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_stake_threshold(1_000_000_000_000u64); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::set_weights { - netuid, - dests: vec![1], - weights: vec![1], - version_key: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::StakeAmountTooLow.into()); - }); -} - -#[test] -fn extension_set_mechanism_weights_rejects_stake_too_low() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network_disable_commit_reveal(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_stake_threshold(1_000_000_000_000u64); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::set_mechanism_weights { - netuid, - mecid: MechId::MAIN, - dests: vec![1], - weights: vec![1], - version_key: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::StakeAmountTooLow.into()); - }); -} - -#[test] -fn extension_batch_set_weights_rejects_mismatched_lengths() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let call = RuntimeCall::SubtensorModule(SubtensorCall::batch_set_weights { - netuids: vec![Compact(netuid)], - weights: vec![], - version_keys: vec![Compact(0_u64)], - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::InputLengthsUnequal.into()); - }); -} - -#[test] -fn extension_batch_set_weights_rejects_stake_too_low() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network_disable_commit_reveal(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_stake_threshold(1_000_000_000_000u64); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::batch_set_weights { - netuids: vec![Compact(netuid)], - weights: vec![vec![(Compact(0u16), Compact(1u16))]], - version_keys: vec![Compact(0u64)], - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::StakeAmountTooLow.into()); - }); -} - -#[test] -fn extension_commit_weights_rejects_stake_too_low() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_stake_threshold(1_000_000_000_000u64); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::commit_weights { - netuid, - commit_hash: H256::zero(), - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::StakeAmountTooLow.into()); - }); -} - -#[test] -fn extension_commit_mechanism_weights_rejects_stake_too_low() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_stake_threshold(1_000_000_000_000u64); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::commit_mechanism_weights { - netuid, - mecid: MechId::MAIN, - commit_hash: H256::zero(), - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::StakeAmountTooLow.into()); - }); -} - -#[test] -fn extension_batch_commit_weights_rejects_mismatched_lengths() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let call = RuntimeCall::SubtensorModule(SubtensorCall::batch_commit_weights { - netuids: vec![Compact(netuid)], - commit_hashes: vec![], - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::InputLengthsUnequal.into()); - }); -} - -#[test] -fn extension_reveal_weights_rejects_stake_too_low() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - add_network(netuid, 1, 0); - SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_stake_threshold(1_000_000_000_000u64); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::reveal_weights { - netuid, - uids: vec![0], - values: vec![1], - salt: vec![1], - version_key: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::StakeAmountTooLow.into()); - }); -} - -#[test] -fn extension_reveal_weights_rejects_commit_not_found() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_stake_threshold(0); - add_balance_to_coldkey_account(&hotkey, 1_000_000_000_000_u64.into()); - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - TaoBalance::from(500_000_000_000_u64) - )); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::reveal_weights { - netuid, - uids: vec![0], - values: vec![1], - salt: vec![1], - version_key: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::CommitNotFound.into()); - }); -} - -#[test] -fn extension_reveal_mechanism_weights_rejects_commit_not_found() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_stake_threshold(0); - add_balance_to_coldkey_account(&hotkey, 1_000_000_000_000_u64.into()); - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - TaoBalance::from(500_000_000_000_u64) - )); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::reveal_mechanism_weights { - netuid, - mecid: MechId::MAIN, - uids: vec![0], - values: vec![1], - salt: vec![1], - version_key: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::CommitNotFound.into()); - }); -} - -#[test] -fn extension_reveal_mechanism_weights_accepts_valid_commit() { - assert_reveal_mechanism_weights_accepts_valid_commit(MechId::MAIN, None); -} - -#[test] -fn extension_reveal_mechanism_weights_accepts_valid_non_main_mechanism_commit() { - assert_reveal_mechanism_weights_accepts_valid_commit( - MechId::from(1u8), - Some(MechId::from(2u8)), - ); -} - -fn assert_reveal_mechanism_weights_accepts_valid_commit( - mecid: MechId, - mechanism_count: Option, -) { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - let uids = vec![0]; - let values = vec![1]; - let salt = vec![1]; - let version_key = 0; - add_network(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - if let Some(mechanism_count) = mechanism_count { - MechanismCountCurrent::::insert(netuid, mechanism_count); - } - SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_stake_threshold(0); - add_balance_to_coldkey_account(&hotkey, 1_000_000_000_000_u64.into()); - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - TaoBalance::from(500_000_000_000_u64) - )); - - let commit_hash = SubtensorModule::get_commit_hash( - &hotkey, - SubtensorModule::get_mechanism_storage_index(netuid, mecid), - &uids, - &values, - &salt, - version_key, - ); - assert_ok!(SubtensorModule::commit_mechanism_weights( - RuntimeOrigin::signed(hotkey), - netuid, - mecid, - commit_hash - )); - step_epochs(1, netuid); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::reveal_mechanism_weights { - netuid, - mecid, - uids, - values, - salt, - version_key, - }); - assert_ok!(validate_signed(hotkey, &call)); - }); -} - -#[test] -fn extension_batch_reveal_weights_rejects_mismatched_vector_lengths() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - add_network(netuid, 1, 0); - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::set_stake_threshold(0); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::batch_reveal_weights { - netuid, - uids_list: vec![vec![0]], - values_list: vec![], - salts_list: vec![vec![1]], - version_keys: vec![0], - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::InputLengthsUnequal.into()); - }); -} - -#[test] -fn extension_commit_timelocked_weights_rejects_invalid_reveal_round() { - new_test_ext(0).execute_with(|| { - LastStoredRound::::put(1_000_u64); - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - add_network(netuid, 1, 0); - SubtensorModule::set_stake_threshold(0); - - let commit = - BoundedVec::>::try_from(vec![0u8]).unwrap(); - let call = RuntimeCall::SubtensorModule(SubtensorCall::commit_timelocked_weights { - netuid, - commit, - reveal_round: 500, - commit_reveal_version: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::InvalidRevealRound.into()); - }); -} - -#[test] -fn extension_commit_timelocked_mechanism_weights_rejects_invalid_reveal_round() { - new_test_ext(0).execute_with(|| { - LastStoredRound::::put(2_000_u64); - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - add_network(netuid, 1, 0); - SubtensorModule::set_stake_threshold(0); - - let commit = - BoundedVec::>::try_from(vec![1u8]).unwrap(); - let call = - RuntimeCall::SubtensorModule(SubtensorCall::commit_timelocked_mechanism_weights { - netuid, - mecid: MechId::MAIN, - commit, - reveal_round: 100, - commit_reveal_version: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::InvalidRevealRound.into()); - }); -} - -#[test] -fn extension_commit_crv3_mechanism_weights_rejects_invalid_reveal_round() { - new_test_ext(0).execute_with(|| { - LastStoredRound::::put(500u64); - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - add_network(netuid, 1, 0); - SubtensorModule::set_stake_threshold(0); - - let commit = - BoundedVec::>::try_from(vec![2u8]).unwrap(); - let call = RuntimeCall::SubtensorModule(SubtensorCall::commit_crv3_mechanism_weights { - netuid, - mecid: MechId::MAIN, - commit, - reveal_round: 100, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::InvalidRevealRound.into()); - }); -} - -#[test] -fn extension_decrease_take_rejects_non_owner_coldkey() { - new_test_ext(0).execute_with(|| { - let owner_ck = U256::from(1); - let other_ck = U256::from(2); - let hotkey = U256::from(3); - crate::Owner::::insert(hotkey, owner_ck); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::decrease_take { - hotkey, - take: MinDelegateTake::::get(), - }); - let err = validate_signed(other_ck, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::NonAssociatedColdKey.into()); - }); -} - -#[test] -fn extension_decrease_take_rejects_missing_hotkey_owner() { - new_test_ext(0).execute_with(|| { - let coldkey = U256::from(1); - let hotkey = U256::from(99); - let call = RuntimeCall::SubtensorModule(SubtensorCall::decrease_take { - hotkey, - take: MinDelegateTake::::get(), - }); - let err = validate_signed(coldkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::HotkeyAccountDoesntExist.into()); - }); -} - -#[test] -fn extension_increase_take_rejects_non_owner_coldkey() { - new_test_ext(0).execute_with(|| { - let owner_ck = U256::from(10); - let other_ck = U256::from(11); - let hotkey = U256::from(12); - crate::Owner::::insert(hotkey, owner_ck); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::increase_take { - hotkey, - take: SubtensorModule::get_min_delegate_take(), - }); - let err = validate_signed(other_ck, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::NonAssociatedColdKey.into()); - }); -} - -#[test] -fn extension_increase_take_validates_take_bounds() { - new_test_ext(0).execute_with(|| { - let coldkey = U256::from(13); - let hotkey = U256::from(14); - crate::Owner::::insert(hotkey, coldkey); - let min_take = SubtensorModule::get_min_delegate_take(); - let max_take = SubtensorModule::get_max_delegate_take(); - let increase_take_call = - |take| RuntimeCall::SubtensorModule(SubtensorCall::increase_take { hotkey, take }); - - let too_low_call = increase_take_call(min_take - 1); - let err = validate_signed(coldkey, &too_low_call).unwrap_err(); - assert_eq!(err, CustomTransactionError::DelegateTakeTooLow.into()); - - let in_scope_call = increase_take_call(min_take); - assert_ok!(validate_signed(coldkey, &in_scope_call)); - - let too_high_call = increase_take_call(max_take + 1); - let err = validate_signed(coldkey, &too_high_call).unwrap_err(); - assert_eq!(err, CustomTransactionError::DelegateTakeTooHigh.into()); - }); -} - -#[test] -fn extension_serve_axon_rejects_unregistered_hotkey() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(40); - let ip = u128::from(u32::from_be_bytes([8, 8, 8, 8])); - let call = RuntimeCall::SubtensorModule(SubtensorCall::serve_axon { - netuid, - version: 1, - ip, - port: 1, - ip_type: 4, - protocol: 0, - placeholder1: 0, - placeholder2: 0, - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!( - err, - CustomTransactionError::HotKeyNotRegisteredInNetwork.into() - ); - }); -} - -#[test] -fn extension_serve_axon_tls_rejects_unregistered_hotkey() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(41); - let ip = u128::from(u32::from_be_bytes([8, 8, 8, 8])); - let call = RuntimeCall::SubtensorModule(SubtensorCall::serve_axon_tls { - netuid, - version: 1, - ip, - port: 1, - ip_type: 4, - protocol: 0, - placeholder1: 0, - placeholder2: 0, - certificate: vec![], - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!( - err, - CustomTransactionError::HotKeyNotRegisteredInNetwork.into() - ); - }); -} - -#[test] -fn extension_serve_prometheus_rejects_unregistered_hotkey() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(99); - let ip = u128::from(u32::from_be_bytes([8, 8, 8, 8])); - let call = RuntimeCall::SubtensorModule(SubtensorCall::serve_prometheus { - netuid, - version: 1, - ip, - port: 1, - ip_type: 4, - }); - let info = call.get_dispatch_info(); - assert_eq!(info.pays_fee, frame_support::dispatch::Pays::No); - - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!( - err, - CustomTransactionError::HotKeyNotRegisteredInNetwork.into() - ); - }); -} - -#[test] -fn extension_associate_evm_key_rejects_uid_not_found() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - add_network(netuid, 1, 0); - let hotkey = U256::from(50); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::associate_evm_key { - netuid, - evm_key: sp_core::H160::zero(), - block_number: 0, - signature: sp_core::ecdsa::Signature::from_raw([0u8; 65]), - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::UidNotFound.into()); - }); -} - -#[test] -fn extension_register_network_rejects_global_rate_limit() { - new_test_ext(0).execute_with(|| { - let limit = 50u64; - NetworkRateLimit::::put(limit); - System::set_block_number(200u64.into()); - SubtensorModule::set_network_last_lock_block(170); - - let coldkey = U256::from(70); - let hotkey = U256::from(71); - let call = RuntimeCall::SubtensorModule(SubtensorCall::register_network { hotkey }); - let err = validate_signed(coldkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::RateLimitExceeded.into()); - }); -} - -#[test] -fn extension_register_network_accepts_after_global_cooldown() { - new_test_ext(0).execute_with(|| { - let limit = 50u64; - NetworkRateLimit::::put(limit); - System::set_block_number(200u64.into()); - SubtensorModule::set_network_last_lock_block(150); - - let coldkey = U256::from(72); - let hotkey = U256::from(73); - let call = RuntimeCall::SubtensorModule(SubtensorCall::register_network { hotkey }); - assert!(validate_signed(coldkey, &call).is_ok()); - }); -} - -#[test] -fn extension_associate_evm_key_rejects_associate_rate_limit() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let tempo: u16 = 2; - let modality: u16 = 2; - add_network(netuid, tempo, modality); - - let coldkey = U256::from(80); - let hotkey = U256::from(81); - let _ = SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); - register_ok_neuron(netuid, hotkey, coldkey, 0); - - let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); - System::set_block_number(300u64.into()); - let now = SubtensorModule::get_current_block_as_u64(); - AssociatedEvmAddress::::insert(netuid, uid, (sp_core::H160::zero(), now)); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::associate_evm_key { - netuid, - evm_key: sp_core::H160::zero(), - block_number: 0, - signature: sp_core::ecdsa::Signature::from_raw([0u8; 65]), - }); - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!( - err, - CustomTransactionError::EvmKeyAssociateRateLimitExceeded.into() - ); - }); -} - -// ============================================================ -// GHSA-2026-006 regression test — security audit (June 2026) -// Fails on the vulnerable code; passes with the fix in this PR. -// ============================================================ -use frame_support::assert_err; - -#[test] -fn ghsa_2026_006_set_weights_paysno_validate_omits_ratelimit() { - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let hotkey = U256::from(1); - let coldkey = U256::from(2); - - // Subnet with commit-reveal disabled so do_set_weights runs the - // per-neuron SetWeightsRateLimit check (weights.rs step 9). - add_network_disable_commit_reveal(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - // Register a real neuron (uid 0) so it exists on-network and its - // LastUpdate vector is sized for set_last_update_for_uid below. - register_ok_neuron(netuid, hotkey, coldkey, 0); - let uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).unwrap(); - - // Drop the min-stake threshold to 0 so the ONLY thing that validate() - // could reject for is the rate limit. This isolates the fix: the - // min-stake mempool gate passes, and the rate-limit gate must now also - // be enforced in validate(). - SubtensorModule::set_stake_threshold(0); - assert!(SubtensorModule::check_weights_min_stake(&hotkey, netuid)); - - // Configure a non-zero per-neuron rate limit and mark this neuron as - // having "just" set weights at the current block, so the next - // set_weights is over-rate. - SubtensorModule::set_weights_set_rate_limit(netuid, 100); - System::set_block_number(10u64.into()); - let current_block = SubtensorModule::get_current_block_as_u64(); - let netuid_index = SubtensorModule::get_mechanism_storage_index(netuid, MechId::MAIN); - SubtensorModule::set_last_update_for_uid(netuid_index, uid, current_block); - - // Sanity: the in-dispatch rate-limit helper now reports over-rate. - assert!(!SubtensorModule::check_rate_limit( - netuid_index, - uid, - current_block - )); - - // Self-weight call (uids/weights == [uid]/[1]) avoids needing a - // validator permit, so dispatch reaches the rate-limit gate. - let call = RuntimeCall::SubtensorModule(SubtensorCall::set_weights { - netuid, - dests: vec![uid], - weights: vec![1], - version_key: 0, - }); - - // (a) set_weights is declared Pays::No -> if validate accepted it, it - // would be included into a block for free. - let info = call.get_dispatch_info(); - assert_eq!(info.pays_fee, frame_support::dispatch::Pays::No); - - // (b) THE FIX: SubtensorTransactionExtension::validate now enforces the - // per-neuron SetWeightsRateLimit. An over-rate set_weights is - // rejected pre-dispatch with RateLimitExceeded, so it can never be - // admitted to the mempool / included for free. - let err = validate_signed(hotkey, &call).unwrap_err(); - assert_eq!(err, CustomTransactionError::RateLimitExceeded.into()); - - // (c) The dispatch path still enforces the rate limit as the - // authoritative check (defence in depth for any tx that slips past - // the pool-level filter, e.g. two over-rate txs in the same block). - assert_err!( - SubtensorModule::set_weights( - RuntimeOrigin::signed(hotkey), - netuid, - vec![uid], - vec![1], - 0, - ), - Error::::SettingWeightsTooFast - ); - }); -} diff --git a/pallets/subtensor/src/tests/weights.rs b/pallets/subtensor/src/tests/weights.rs index 6490b5f824..23318eca4a 100644 --- a/pallets/subtensor/src/tests/weights.rs +++ b/pallets/subtensor/src/tests/weights.rs @@ -3,27 +3,23 @@ use ark_serialize::CanonicalDeserialize; use ark_serialize::CanonicalSerialize; use codec::Compact; -use frame_support::dispatch::DispatchInfo; use frame_support::{ assert_err, assert_ok, dispatch::{DispatchClass, DispatchResult, GetDispatchInfo, Pays}, }; -use frame_system::RawOrigin; use pallet_drand::types::Pulse; use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng}; use scale_info::prelude::collections::HashMap; use sha2::Digest; use sp_core::Encode; -use sp_core::{Get, H256, U256}; -use sp_runtime::traits::{DispatchInfoOf, TransactionExtension}; +use sp_core::{H256, U256}; use sp_runtime::{ BoundedVec, DispatchError, - traits::{BlakeTwo256, ConstU32, Hash, TxBaseImplication}, + traits::{BlakeTwo256, ConstU32, Hash}, }; use sp_std::collections::vec_deque::VecDeque; use substrate_fixed::types::I32F32; -use subtensor_runtime_common::{CustomTransactionError, NetUidStorageIndex, TaoBalance}; -use subtensor_swap_interface::SwapHandler; +use subtensor_runtime_common::NetUidStorageIndex; use tle::{ curves::drand::TinyBLS381, ibe::fullident::Identity, @@ -32,10 +28,8 @@ use tle::{ }; use w3f_bls::EngineBLS; -use super::mock; use super::mock::*; use crate::coinbase::reveal_commits::{LegacyWeightsTlockPayload, WeightsTlockPayload}; -use crate::extensions::SubtensorTransactionExtension; use crate::*; /*************************** pub fn set_weights() tests @@ -88,118 +82,6 @@ fn test_commit_weights_dispatch_info_ok() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::weights::test_commit_weights_validate --exact --show-output --nocapture -#[test] -fn test_commit_weights_validate() { - // Testing the signed extension validate function - // correctly filters this transaction. - - new_test_ext(0).execute_with(|| { - let dests = vec![1, 1]; - let weights = vec![1, 1]; - let netuid = NetUid::from(1); - let salt: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8]; - let version_key: u64 = 0; - let coldkey = U256::from(0); - let hotkey: U256 = U256::from(1); // Add the hotkey field - assert_ne!(hotkey, coldkey); // Ensure hotkey is NOT the same as coldkey !!! - - let who = hotkey; // The hotkey signs this transaction - - let commit_hash: H256 = - BlakeTwo256::hash_of(&(hotkey, netuid, dests, weights, salt, version_key)); - - let call = RuntimeCall::SubtensorModule(SubtensorCall::commit_weights { - netuid, - commit_hash, - }); - - // Create netuid - add_network(netuid, 1, 0); - // Register the hotkey - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - - add_balance_to_coldkey_account(&hotkey, 20_000_000_000_000_000_u64.into()); - - let min_stake = 500_000_000_000_u64; - let reserve = min_stake * 1000; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - - // Stake some TAO and read what get_total_stake_for_hotkey it gets - // It will be a different value due to the slippage - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - min_stake.into() - )); - let min_stake_with_slippage = SubtensorModule::get_total_stake_for_hotkey(&hotkey); - - // Set the minimum stake above what hotkey has - SubtensorModule::set_stake_threshold(min_stake_with_slippage.to_u64() + 1); - - // Submit to the signed extension validate function - let info = DispatchInfoOf::<::RuntimeCall>::default(); - let extension = SubtensorTransactionExtension::::new(); - // Submit to the signed extension validate function - let result_no_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result_no_stake.unwrap_err(), - CustomTransactionError::StakeAmountTooLow.into() - ); - - // Set the minimum stake equal to what hotkey has - SubtensorModule::set_stake_threshold(min_stake_with_slippage.into()); - - // Submit to the signed extension validate function - let result_min_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Now the call should pass - assert_ok!(result_min_stake); - - // Try with more stake than minimum - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - DefaultMinStake::::get() * 10.into() - )); - - // Verify stake is more than minimum - assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) > min_stake_with_slippage); - - let result_more_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // The call should still pass - assert_ok!(result_more_stake); - }); -} - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::weights::test_reveal_weights_dispatch_info_ok --exact --show-output --nocapture #[test] fn test_reveal_weights_dispatch_info_ok() { @@ -224,494 +106,6 @@ fn test_reveal_weights_dispatch_info_ok() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::weights::test_set_weights_validate --exact --show-output --nocapture -#[test] -fn test_set_weights_validate() { - // Testing the signed extension validate function - // correctly filters the `set_weights` transaction. - - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let coldkey = U256::from(0); - let hotkey: U256 = U256::from(1); - assert_ne!(hotkey, coldkey); - - let who = hotkey; // The hotkey signs this transaction - - let call = RuntimeCall::SubtensorModule(SubtensorCall::set_weights { - netuid, - dests: vec![1, 1], - weights: vec![1, 1], - version_key: 0, - }); - - // Create netuid (commit-reveal off so `set_weights` matches extension / extrinsic) - add_network_disable_commit_reveal(netuid, 1, 0); - setup_reserves( - netuid, - 1_000_000_000_000_u64.into(), - 1_000_000_000_000_u64.into(), - ); - // Register the hotkey - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - - add_balance_to_coldkey_account(&hotkey, 20_000_000_000_000_000_u64.into()); - - let min_stake = TaoBalance::from(500_000_000_000_u64); - - // Set the minimum stake - SubtensorModule::set_stake_threshold(min_stake.into()); - - // Verify stake is less than minimum - assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); - let info: DispatchInfo = - DispatchInfoOf::<::RuntimeCall>::default(); - - let extension = SubtensorTransactionExtension::::new(); - // Submit to the signed extension validate function - let result_no_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail due to insufficient stake - assert_eq!( - result_no_stake.unwrap_err(), - CustomTransactionError::StakeAmountTooLow.into() - ); - - // Increase the stake and make it to be equal to the minimum threshold - let fee = - ::SwapInterface::approx_fee_amount(netuid.into(), min_stake); - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - min_stake + fee - )); - let min_stake_with_slippage = SubtensorModule::get_total_stake_for_hotkey(&hotkey); - - // Set the minimum stake to what the hotkey has - SubtensorModule::set_stake_threshold(min_stake_with_slippage.into()); - - // Submit to the signed extension validate function - let result_min_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Now the call should pass - assert_ok!(result_min_stake); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::weights::test_reveal_weights_validate --exact --show-output --nocapture -#[test] -fn test_reveal_weights_validate() { - // Testing the signed extension validate function - // correctly filters this transaction. - - new_test_ext(0).execute_with(|| { - let dests = vec![1, 1]; - let weights = vec![1, 1]; - let netuid = NetUid::from(1); - let salt: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8]; - let version_key: u64 = 0; - let coldkey = U256::from(0); - let hotkey: U256 = U256::from(1); // Add the hotkey field - let hotkey2: U256 = U256::from(2); - let tempo = 1; - assert_ne!(hotkey, coldkey); // Ensure hotkey is NOT the same as coldkey !!! - let fee: u64 = 0; // FIXME: DefaultStakingFee is deprecated - - let who = hotkey; // The hotkey signs this transaction - - let call = RuntimeCall::SubtensorModule(SubtensorCall::reveal_weights { - netuid, - uids: dests.clone(), - values: weights.clone(), - salt: salt.clone(), - version_key, - }); - - let commit_hash: H256 = SubtensorModule::get_commit_hash( - &who, - NetUidStorageIndex::from(netuid), - &dests, - &weights, - &salt, - version_key, - ); - // Counter is 0 on a fresh subnet; tag the commit with epoch 0. - let commit_epoch: u64 = 0; - - // Create netuid - add_network(netuid, tempo, 0); - // Register the hotkey - SubtensorModule::append_neuron(netuid, &hotkey, 0); - SubtensorModule::append_neuron(netuid, &hotkey2, 0); - crate::Owner::::insert(hotkey, coldkey); - crate::Owner::::insert(hotkey2, coldkey); - add_balance_to_coldkey_account(&hotkey, 20_000_000_000_000_000_u64.into()); - - let min_stake = TaoBalance::from(500_000_000_000_u64); - // Set the minimum stake - SubtensorModule::set_stake_threshold(min_stake.into()); - - // Verify stake is less than minimum - assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); - let info: DispatchInfo = - DispatchInfoOf::<::RuntimeCall>::default(); - - let extension = SubtensorTransactionExtension::::new(); - // Submit to the signed extension validate function - let result_no_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result_no_stake.unwrap_err(), - CustomTransactionError::StakeAmountTooLow.into() - ); - - // Increase the stake to be equal to the minimum - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - min_stake + fee.into() - )); - - // Verify stake is equal to minimum - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey), - min_stake - ); - - // Try to reveal weights without a commit - let result_no_commit = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - assert_eq!( - result_no_commit.unwrap_err(), - CustomTransactionError::CommitNotFound.into() - ); - - // Add the commit to the hotkey - WeightCommits::::mutate(NetUidStorageIndex::from(netuid), hotkey, |maybe_commits| { - let mut commits: VecDeque<(H256, u64, u64, u64)> = - maybe_commits.take().unwrap_or_default(); - commits.push_back((commit_hash, commit_epoch, 0, 0)); - *maybe_commits = Some(commits); - }); - - // Try to reveal weights in wrong epoch - let result_invalid_epoch = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - assert_eq!( - result_invalid_epoch.unwrap_err(), - CustomTransactionError::CommitBlockNotInRevealRange.into() - ); - - // Advance the epoch counter into the commit's reveal epoch - // (`commit_epoch + reveal_period`); pin the scheduler so the look-ahead - // does not overshoot. - let reveal_period = SubtensorModule::get_reveal_period(netuid); - SubnetEpochIndex::::insert(netuid, commit_epoch + reveal_period); - LastEpochBlock::::insert(netuid, SubtensorModule::get_current_block_as_u64()); - PendingEpochAt::::insert(netuid, 0); - - // Submit to the signed extension validate function - let result_valid_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Now the call should pass - assert_ok!(result_valid_stake); - - // Try with more stake than minimum - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - DefaultMinStake::::get() * 10.into() - )); - - // Verify stake is more than minimum - assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) > min_stake); - - let result_more_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // The call should still pass - assert_ok!(result_more_stake); - - // Advance the counter past the commit's reveal epoch — now too late. - SubnetEpochIndex::::insert(netuid, commit_epoch + reveal_period + 1); - LastEpochBlock::::insert(netuid, SubtensorModule::get_current_block_as_u64()); - - // Submit to the signed extension validate function - let result_too_late = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - - assert_eq!( - result_too_late.unwrap_err(), - CustomTransactionError::CommitBlockNotInRevealRange.into() - ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::weights::test_batch_reveal_weights_validate --exact --show-output --nocapture -#[test] -fn test_batch_reveal_weights_validate() { - // Testing the signed extension validate function - // correctly filters batch_reveal_weights transaction for all error conditions. - - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let coldkey = U256::from(0); - let hotkey: U256 = U256::from(1); - let hotkey2: U256 = U256::from(2); - let tempo = 1; - assert_ne!(hotkey, coldkey); // Ensure hotkey is NOT the same as coldkey !!! - - let who = hotkey; // The hotkey signs this transaction - - // Create test data for batch operations - let uids_list: Vec> = vec![vec![0, 1], vec![1, 0]]; - let values_list: Vec> = vec![vec![10, 20], vec![30, 40]]; - let salts_list: Vec> = - vec![vec![1, 2, 3, 4, 5, 6, 7, 8], vec![8, 7, 6, 5, 4, 3, 2, 1]]; - let version_keys: Vec = vec![0, 0]; - - // Create the batch reveal call - let call = RuntimeCall::SubtensorModule(SubtensorCall::batch_reveal_weights { - netuid, - uids_list: uids_list.clone(), - values_list: values_list.clone(), - salts_list: salts_list.clone(), - version_keys: version_keys.clone(), - }); - - // Create netuid - add_network(netuid, tempo, 0); - // Register the hotkeys - SubtensorModule::append_neuron(netuid, &hotkey, 0); - SubtensorModule::append_neuron(netuid, &hotkey2, 0); - crate::Owner::::insert(hotkey, coldkey); - crate::Owner::::insert(hotkey2, coldkey); - add_balance_to_coldkey_account(&hotkey, 20_000_000_000_000_000_u64.into()); - SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - - let min_stake = TaoBalance::from(500_000_000_000_u64); - // Set the minimum stake - SubtensorModule::set_stake_threshold(min_stake.into()); - - let info: DispatchInfo = - DispatchInfoOf::<::RuntimeCall>::default(); - let extension = SubtensorTransactionExtension::::new(); - - // Test 1: StakeAmountTooLow - Verify stake is less than minimum - assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); - - let result_no_stake = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail with StakeAmountTooLow - assert_eq!( - result_no_stake.unwrap_err(), - CustomTransactionError::StakeAmountTooLow.into() - ); - - // Increase the stake to be equal to the minimum - assert_ok!(SubtensorModule::do_add_stake( - RuntimeOrigin::signed(hotkey), - hotkey, - netuid, - min_stake - )); - - // Verify stake is now sufficient - assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) >= min_stake); - - // Test 2: InputLengthsUnequal - Test unequal input lengths - let call_unequal_lengths = - RuntimeCall::SubtensorModule(SubtensorCall::batch_reveal_weights { - netuid, - uids_list: vec![vec![0, 1], vec![1, 0], vec![2, 3]], // Extra element - values_list: values_list.clone(), - salts_list: salts_list.clone(), - version_keys: version_keys.clone(), - }); - - let result_unequal_lengths = extension.validate( - RawOrigin::Signed(who).into(), - &call_unequal_lengths, - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - - assert_eq!( - result_unequal_lengths.unwrap_err(), - CustomTransactionError::InputLengthsUnequal.into() - ); - - // Should fail - but this error is checked in do_batch_reveal_weights, - // so the signed extension should pass but the actual call should fail - // We'll test the actual error in the direct function call below - - // Test 3: CommitNotFound - Try to reveal without any commits - let result = SubtensorModule::do_batch_reveal_weights( - RuntimeOrigin::signed(hotkey), - netuid, - uids_list.clone(), - values_list.clone(), - salts_list.clone(), - version_keys.clone(), - ); - assert_err!(result, Error::::NoWeightsCommitFound); - - // Now create commits for testing reveal range errors - let commit_hashes: Vec = uids_list - .iter() - .zip(values_list.iter()) - .zip(salts_list.iter().zip(version_keys.iter())) - .map(|((uids, values), (salt, version_key))| { - BlakeTwo256::hash_of(&( - hotkey, - netuid, - uids.clone(), - values.clone(), - salt.clone(), - *version_key, - )) - }) - .collect(); - - // Commit weights for each hash - for commit_hash in &commit_hashes { - assert_ok!(SubtensorModule::commit_weights( - RuntimeOrigin::signed(hotkey), - netuid, - *commit_hash - )); - } - - // Epoch all the commits were tagged with (committed in a tight loop). - let commit_epoch = - crate::WeightCommits::::get(NetUidStorageIndex::from(netuid), hotkey) - .and_then(|q| q.back().map(|(_, e, _, _)| *e)) - .expect("commit stored"); - let reveal_period = SubtensorModule::get_reveal_period(netuid); - - // Test 5: CommitBlockNotInRevealRange - Try to reveal too early - let result_too_early = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - assert_eq!( - result_too_early.unwrap_err(), - CustomTransactionError::CommitBlockNotInRevealRange.into() - ); - - // Advance the epoch counter into the commits' reveal epoch. - SubnetEpochIndex::::insert(netuid, commit_epoch + reveal_period); - LastEpochBlock::::insert(netuid, SubtensorModule::get_current_block_as_u64()); - PendingEpochAt::::insert(netuid, 0); - - // Now the call should pass the signed extension validation - let result_valid_time = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - assert_ok!(result_valid_time); - - // Test 6: CommitBlockNotInRevealRange - reveal too late (counter past reveal epoch) - SubnetEpochIndex::::insert(netuid, commit_epoch + reveal_period + 1); - LastEpochBlock::::insert(netuid, SubtensorModule::get_current_block_as_u64()); - - let result_too_late = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - assert_eq!( - result_too_late.unwrap_err(), - CustomTransactionError::CommitBlockNotInRevealRange.into() - ); - }); -} - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::weights::test_set_weights_is_root_error --exact --show-output --nocapture #[test] fn test_set_weights_is_root_error() { diff --git a/pallets/subtensor/src/weights.rs b/pallets/subtensor/src/weights.rs index e84c260c72..84cb42ae8c 100644 --- a/pallets/subtensor/src/weights.rs +++ b/pallets/subtensor/src/weights.rs @@ -2,16 +2,16 @@ //! Autogenerated weights for `pallet_subtensor` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 49.1.0 -//! DATE: 2026-06-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2026-06-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runnervm3jyl0`, CPU: `AMD EPYC 9V74 80-Core Processor` +//! HOSTNAME: `user-laptop`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` // Executed Command: -// /home/runner/work/subtensor/subtensor/target/production/node-subtensor +// /Users/user/Work/subtensor/target/production/node-subtensor // benchmark // pallet -// --runtime=/home/runner/work/subtensor/subtensor/target/production/wbuild/node-subtensor-runtime/node_subtensor_runtime.compact.compressed.wasm +// --runtime=/Users/user/Work/subtensor/target/production/wbuild/node-subtensor-runtime/node_subtensor_runtime.compact.compressed.wasm // --genesis-builder=runtime // --genesis-builder-preset=benchmark // --wasm-execution=compiled @@ -22,8 +22,8 @@ // --no-storage-info // --no-min-squares // --no-median-slopes -// --output=/tmp/tmp.2HksoV8klE -// --template=/home/runner/work/subtensor/subtensor/.maintain/frame-weight-template.hbs +// --output=/Users/user/Work/subtensor/pallets/subtensor/src/weights.rs +// --template=/Users/user/Work/subtensor/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -96,6 +96,12 @@ pub trait WeightInfo { fn set_tempo() -> Weight; fn set_activity_cutoff_factor() -> Weight; fn trigger_epoch() -> Weight; + fn check_coldkey_swap_extension() -> Weight; + fn check_weights_extension() -> Weight; + fn check_rate_limits_extension() -> Weight; + fn check_delegate_take_extension() -> Weight; + fn check_serving_endpoints_extension() -> Weight; + fn check_evm_key_association_extension() -> Weight; } /// Weights for `pallet_subtensor` using the Substrate node and recommended hardware. @@ -177,10 +183,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) fn register() -> Weight { // Proof Size summary in bytes: - // Measured: `1837` + // Measured: `1865` // Estimated: `6148` - // Minimum execution time: 340_604_000 picoseconds. - Weight::from_parts(344_520_000, 6148) + // Minimum execution time: 148_000_000 picoseconds. + Weight::from_parts(155_000_000, 6148) .saturating_add(T::DbWeight::get().reads(34_u64)) .saturating_add(T::DbWeight::get().writes(29_u64)) } @@ -220,10 +226,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `188792` - // Estimated: `10327382` - // Minimum execution time: 16_142_608_000 picoseconds. - Weight::from_parts(16_400_997_000, 10327382) + // Measured: `188820` + // Estimated: `10327410` + // Minimum execution time: 6_739_000_000 picoseconds. + Weight::from_parts(6_870_000_000, 10327410) .saturating_add(T::DbWeight::get().reads(4112_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -293,39 +299,39 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2226` // Estimated: `8727` - // Minimum execution time: 665_334_000 picoseconds. - Weight::from_parts(685_664_000, 8727) + // Minimum execution time: 280_000_000 picoseconds. + Weight::from_parts(284_000_000, 8727) .saturating_add(T::DbWeight::get().reads(32_u64)) .saturating_add(T::DbWeight::get().writes(16_u64)) } - /// Storage: `SubtensorModule::IsNetworkMember` (r:2 w:0) - /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Axons` (r:1 w:1) /// Proof: `SubtensorModule::Axons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) fn serve_axon() -> Weight { // Proof Size summary in bytes: - // Measured: `801` - // Estimated: `6741` - // Minimum execution time: 31_927_000 picoseconds. - Weight::from_parts(33_199_000, 6741) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `713` + // Estimated: `4178` + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(16_000_000, 4178) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `SubtensorModule::IsNetworkMember` (r:2 w:0) - /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Prometheus` (r:1 w:1) /// Proof: `SubtensorModule::Prometheus` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) fn serve_prometheus() -> Weight { // Proof Size summary in bytes: - // Measured: `774` - // Estimated: `6714` - // Minimum execution time: 28_011_000 picoseconds. - Weight::from_parts(29_073_000, 6714) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `812` + // Estimated: `4277` + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(16_000_000, 4277) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -404,10 +410,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) fn burned_register() -> Weight { // Proof Size summary in bytes: - // Measured: `1770` + // Measured: `1798` // Estimated: `6148` - // Minimum execution time: 337_589_000 picoseconds. - Weight::from_parts(341_856_000, 6148) + // Minimum execution time: 149_000_000 picoseconds. + Weight::from_parts(154_000_000, 6148) .saturating_add(T::DbWeight::get().reads(34_u64)) .saturating_add(T::DbWeight::get().writes(29_u64)) } @@ -457,10 +463,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) fn root_register() -> Weight { // Proof Size summary in bytes: - // Measured: `1482` - // Estimated: `4947` - // Minimum execution time: 100_028_000 picoseconds. - Weight::from_parts(102_953_000, 4947) + // Measured: `1516` + // Estimated: `4981` + // Minimum execution time: 46_000_000 picoseconds. + Weight::from_parts(47_000_000, 4981) .saturating_add(T::DbWeight::get().reads(19_u64)) .saturating_add(T::DbWeight::get().writes(16_u64)) } @@ -558,6 +564,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaOut` (r:0 w:1) /// Proof: `SubtensorModule::SubnetAlphaOut` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:0 w:1) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:0 w:1) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Uids` (r:0 w:1) @@ -578,10 +586,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1532` // Estimated: `9947` - // Minimum execution time: 266_053_000 picoseconds. - Weight::from_parts(272_392_000, 9947) + // Minimum execution time: 123_000_000 picoseconds. + Weight::from_parts(125_000_000, 9947) .saturating_add(T::DbWeight::get().reads(40_u64)) - .saturating_add(T::DbWeight::get().writes(47_u64)) + .saturating_add(T::DbWeight::get().writes(48_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -595,27 +603,35 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastUpdate` (r:1 w:1) /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) - /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) + /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::BlocksSinceLastStep` (r:1 w:0) + /// Proof: `SubtensorModule::BlocksSinceLastStep` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:1 w:0) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) fn commit_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1071` - // Estimated: `4536` - // Minimum execution time: 57_885_000 picoseconds. - Weight::from_parts(58_817_000, 4536) - .saturating_add(T::DbWeight::get().reads(10_u64)) + // Measured: `1249` + // Estimated: `4714` + // Minimum execution time: 30_000_000 picoseconds. + Weight::from_parts(31_000_000, 4714) + .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) @@ -650,11 +666,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn reveal_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1589` - // Estimated: `7529` - // Minimum execution time: 105_065_000 picoseconds. - Weight::from_parts(107_229_000, 7529) - .saturating_add(T::DbWeight::get().reads(18_u64)) + // Measured: `1650` + // Estimated: `7590` + // Minimum execution time: 49_000_000 picoseconds. + Weight::from_parts(52_000_000, 7590) + .saturating_add(T::DbWeight::get().reads(19_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::TxChildkeyTakeRateLimit` (r:0 w:1) @@ -663,8 +679,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_036_000 picoseconds. - Weight::from_parts(4_397_000, 0) + // Minimum execution time: 2_000_000 picoseconds. + Weight::from_parts(2_000_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -685,8 +701,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1033` // Estimated: `4498` - // Minimum execution time: 51_045_000 picoseconds. - Weight::from_parts(51_967_000, 4498) + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(25_000_000, 4498) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -702,8 +718,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `694` // Estimated: `4159` - // Minimum execution time: 43_204_000 picoseconds. - Weight::from_parts(45_056_000, 4159) + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(23_000_000, 4159) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -731,6 +747,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::TotalHotkeyShares` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalHotkeySharesV2` (r:2 w:2) /// Proof: `SubtensorModule::TotalHotkeySharesV2` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::StakingColdkeys` (r:1 w:0) + /// Proof: `SubtensorModule::StakingColdkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::OwnedHotkeys` (r:2 w:2) /// Proof: `SubtensorModule::OwnedHotkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::UnlockRate` (r:1 w:0) @@ -749,9 +767,9 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2110` // Estimated: `13000` - // Minimum execution time: 285_883_000 picoseconds. - Weight::from_parts(289_268_000, 13000) - .saturating_add(T::DbWeight::get().reads(36_u64)) + // Minimum execution time: 128_000_000 picoseconds. + Weight::from_parts(132_000_000, 13000) + .saturating_add(T::DbWeight::get().reads(37_u64)) .saturating_add(T::DbWeight::get().writes(15_u64)) } /// Storage: `System::Account` (r:2 w:2) @@ -780,6 +798,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::TotalHotkeyShares` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalHotkeySharesV2` (r:2 w:2) /// Proof: `SubtensorModule::TotalHotkeySharesV2` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::StakingColdkeys` (r:1 w:0) + /// Proof: `SubtensorModule::StakingColdkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::OwnedHotkeys` (r:2 w:2) /// Proof: `SubtensorModule::OwnedHotkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::UnlockRate` (r:1 w:0) @@ -800,9 +820,9 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2166` // Estimated: `13056` - // Minimum execution time: 308_517_000 picoseconds. - Weight::from_parts(314_044_000, 13056) - .saturating_add(T::DbWeight::get().reads(36_u64)) + // Minimum execution time: 138_000_000 picoseconds. + Weight::from_parts(144_000_000, 13056) + .saturating_add(T::DbWeight::get().reads(37_u64)) .saturating_add(T::DbWeight::get().writes(19_u64)) } /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) @@ -813,8 +833,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `665` // Estimated: `4130` - // Minimum execution time: 20_170_000 picoseconds. - Weight::from_parts(20_820_000, 4130) + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(11_000_000, 4130) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -826,8 +846,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `613` // Estimated: `4078` - // Minimum execution time: 16_435_000 picoseconds. - Weight::from_parts(17_065_000, 4078) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 4078) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -839,14 +859,16 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_750_000 picoseconds. - Weight::from_parts(7_190_000, 0) + // Minimum execution time: 3_000_000 picoseconds. + Weight::from_parts(4_000_000, 0) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) @@ -881,11 +903,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn batch_reveal_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `2094` - // Estimated: `8034` - // Minimum execution time: 414_593_000 picoseconds. - Weight::from_parts(422_245_000, 8034) - .saturating_add(T::DbWeight::get().reads(18_u64)) + // Measured: `2155` + // Estimated: `8095` + // Minimum execution time: 191_000_000 picoseconds. + Weight::from_parts(197_000_000, 8095) + .saturating_add(T::DbWeight::get().reads(19_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -918,8 +940,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1754` // Estimated: `5219` - // Minimum execution time: 173_126_000 picoseconds. - Weight::from_parts(174_428_000, 5219) + // Minimum execution time: 74_000_000 picoseconds. + Weight::from_parts(75_000_000, 5219) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -951,8 +973,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1754` // Estimated: `5219` - // Minimum execution time: 167_228_000 picoseconds. - Weight::from_parts(169_080_000, 5219) + // Minimum execution time: 72_000_000 picoseconds. + Weight::from_parts(73_000_000, 5219) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -972,8 +994,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1118` // Estimated: `4583` - // Minimum execution time: 37_305_000 picoseconds. - Weight::from_parts(38_226_000, 4583) + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 4583) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -1043,8 +1065,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2226` // Estimated: `8727` - // Minimum execution time: 862_916_000 picoseconds. - Weight::from_parts(876_506_000, 8727) + // Minimum execution time: 357_000_000 picoseconds. + Weight::from_parts(371_000_000, 8727) .saturating_add(T::DbWeight::get().reads(32_u64)) .saturating_add(T::DbWeight::get().writes(16_u64)) } @@ -1080,8 +1102,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1979` // Estimated: `7919` - // Minimum execution time: 218_613_000 picoseconds. - Weight::from_parts(219_955_000, 7919) + // Minimum execution time: 95_000_000 picoseconds. + Weight::from_parts(96_000_000, 7919) .saturating_add(T::DbWeight::get().reads(19_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -1137,8 +1159,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2142` // Estimated: `10557` - // Minimum execution time: 559_437_000 picoseconds. - Weight::from_parts(573_518_000, 10557) + // Minimum execution time: 236_000_000 picoseconds. + Weight::from_parts(238_000_000, 10557) .saturating_add(T::DbWeight::get().reads(28_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -1192,8 +1214,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2176` // Estimated: `10591` - // Minimum execution time: 739_182_000 picoseconds. - Weight::from_parts(755_287_000, 10591) + // Minimum execution time: 308_000_000 picoseconds. + Weight::from_parts(315_000_000, 10591) .saturating_add(T::DbWeight::get().reads(27_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -1265,8 +1287,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2662` // Estimated: `11077` - // Minimum execution time: 949_273_000 picoseconds. - Weight::from_parts(964_857_000, 11077) + // Minimum execution time: 397_000_000 picoseconds. + Weight::from_parts(404_000_000, 11077) .saturating_add(T::DbWeight::get().reads(47_u64)) .saturating_add(T::DbWeight::get().writes(24_u64)) } @@ -1306,8 +1328,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1988` // Estimated: `7928` - // Minimum execution time: 250_861_000 picoseconds. - Weight::from_parts(253_195_000, 7928) + // Minimum execution time: 108_000_000 picoseconds. + Weight::from_parts(109_000_000, 7928) .saturating_add(T::DbWeight::get().reads(18_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -1379,8 +1401,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2505` // Estimated: `10920` - // Minimum execution time: 728_698_000 picoseconds. - Weight::from_parts(746_774_000, 10920) + // Minimum execution time: 312_000_000 picoseconds. + Weight::from_parts(317_000_000, 10920) .saturating_add(T::DbWeight::get().reads(47_u64)) .saturating_add(T::DbWeight::get().writes(24_u64)) } @@ -1396,23 +1418,31 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastUpdate` (r:1 w:1) /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) - /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) + /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::BlocksSinceLastStep` (r:1 w:0) + /// Proof: `SubtensorModule::BlocksSinceLastStep` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:1 w:0) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightsSetRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::WeightsSetRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) + /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) fn batch_commit_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1122` - // Estimated: `4587` - // Minimum execution time: 123_562_000 picoseconds. - Weight::from_parts(125_566_000, 4587) - .saturating_add(T::DbWeight::get().reads(11_u64)) + // Measured: `1300` + // Estimated: `4765` + // Minimum execution time: 67_000_000 picoseconds. + Weight::from_parts(67_000_000, 4765) + .saturating_add(T::DbWeight::get().reads(15_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) @@ -1449,10 +1479,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn batch_set_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1426` - // Estimated: `7366` - // Minimum execution time: 97_624_000 picoseconds. - Weight::from_parts(100_468_000, 7366) + // Measured: `1455` + // Estimated: `7395` + // Minimum execution time: 45_000_000 picoseconds. + Weight::from_parts(46_000_000, 7395) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -1468,8 +1498,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `830` // Estimated: `4295` - // Minimum execution time: 26_830_000 picoseconds. - Weight::from_parts(27_561_000, 4295) + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(14_000_000, 4295) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -1487,8 +1517,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `923` // Estimated: `4388` - // Minimum execution time: 33_029_000 picoseconds. - Weight::from_parts(34_211_000, 4388) + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(17_000_000, 4388) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -1586,6 +1616,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaOut` (r:0 w:1) /// Proof: `SubtensorModule::SubnetAlphaOut` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:0 w:1) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:0 w:1) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Uids` (r:0 w:1) @@ -1606,24 +1638,24 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1468` // Estimated: `9883` - // Minimum execution time: 266_604_000 picoseconds. - Weight::from_parts(276_799_000, 9883) + // Minimum execution time: 121_000_000 picoseconds. + Weight::from_parts(123_000_000, 9883) .saturating_add(T::DbWeight::get().reads(39_u64)) - .saturating_add(T::DbWeight::get().writes(46_u64)) + .saturating_add(T::DbWeight::get().writes(47_u64)) } - /// Storage: `SubtensorModule::IsNetworkMember` (r:2 w:0) - /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Axons` (r:1 w:1) /// Proof: `SubtensorModule::Axons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) fn serve_axon_tls() -> Weight { // Proof Size summary in bytes: - // Measured: `772` - // Estimated: `6712` - // Minimum execution time: 31_506_000 picoseconds. - Weight::from_parts(32_528_000, 6712) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `684` + // Estimated: `4149` + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(13_000_000, 4149) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::OwnedHotkeys` (r:1 w:0) @@ -1636,8 +1668,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `889` // Estimated: `6829` - // Minimum execution time: 29_043_000 picoseconds. - Weight::from_parts(30_816_000, 6829) + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(14_000_000, 6829) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -1649,12 +1681,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `595` // Estimated: `4060` - // Minimum execution time: 15_503_000 picoseconds. - Weight::from_parts(16_204_000, 4060) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(8_000_000, 4060) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `SubtensorModule::Owner` (r:1 w:2) + /// Storage: `SubtensorModule::Owner` (r:2 w:2) /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastRateLimitedBlock` (r:4 w:7) /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -1666,14 +1698,20 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::RootClaimable` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalHotkeyAlpha` (r:9 w:8) /// Proof: `SubtensorModule::TotalHotkeyAlpha` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::RootClaimed` (r:1 w:0) + /// Proof: `SubtensorModule::RootClaimed` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworksAdded` (r:6 w:0) + /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ChildKeys` (r:10 w:10) + /// Proof: `SubtensorModule::ChildKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastHotkeySwapOnNetuid` (r:4 w:4) + /// Proof: `SubtensorModule::LastHotkeySwapOnNetuid` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalIssuance` (r:1 w:1) /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Alpha` (r:9 w:0) /// Proof: `SubtensorModule::Alpha` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::AlphaV2` (r:9 w:8) /// Proof: `SubtensorModule::AlphaV2` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::NetworksAdded` (r:6 w:0) - /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetOwnerHotkey` (r:5 w:0) /// Proof: `SubtensorModule::SubnetOwnerHotkey` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::HotkeyLock` (r:5 w:0) @@ -1682,8 +1720,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::DecayingHotkeyLock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::OwnedHotkeys` (r:1 w:1) /// Proof: `SubtensorModule::OwnedHotkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::ChildKeys` (r:10 w:10) - /// Proof: `SubtensorModule::ChildKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ChildkeyTake` (r:5 w:0) + /// Proof: `SubtensorModule::ChildkeyTake` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ParentKeys` (r:10 w:10) /// Proof: `SubtensorModule::ParentKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::PendingChildKeys` (r:10 w:0) @@ -1724,12 +1762,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) fn swap_hotkey() -> Weight { // Proof Size summary in bytes: - // Measured: `3131` - // Estimated: `28871` - // Minimum execution time: 1_193_554_000 picoseconds. - Weight::from_parts(1_201_736_000, 28871) - .saturating_add(T::DbWeight::get().reads(171_u64)) - .saturating_add(T::DbWeight::get().writes(95_u64)) + // Measured: `3172` + // Estimated: `28912` + // Minimum execution time: 529_000_000 picoseconds. + Weight::from_parts(543_000_000, 28912) + .saturating_add(T::DbWeight::get().reads(182_u64)) + .saturating_add(T::DbWeight::get().writes(99_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:1) /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -1741,8 +1779,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `818` // Estimated: `4283` - // Minimum execution time: 23_084_000 picoseconds. - Weight::from_parts(23_836_000, 4283) + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(11_000_000, 4283) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1756,8 +1794,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `774` // Estimated: `9189` - // Minimum execution time: 24_587_000 picoseconds. - Weight::from_parts(25_608_000, 9189) + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(13_000_000, 9189) .saturating_add(T::DbWeight::get().reads(6_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -1818,8 +1856,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2235` // Estimated: `11306` - // Minimum execution time: 695_268_000 picoseconds. - Weight::from_parts(708_618_000, 11306) + // Minimum execution time: 296_000_000 picoseconds. + Weight::from_parts(302_000_000, 11306) .saturating_add(T::DbWeight::get().reads(43_u64)) .saturating_add(T::DbWeight::get().writes(25_u64)) } @@ -1873,8 +1911,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2176` // Estimated: `10591` - // Minimum execution time: 763_548_000 picoseconds. - Weight::from_parts(778_691_000, 10591) + // Minimum execution time: 317_000_000 picoseconds. + Weight::from_parts(323_000_000, 10591) .saturating_add(T::DbWeight::get().reads(27_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -1988,6 +2026,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaOut` (r:0 w:1) /// Proof: `SubtensorModule::SubnetAlphaOut` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:0 w:1) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:0 w:1) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Uids` (r:0 w:1) @@ -2011,13 +2051,13 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1835 + k * (44 ±0)` // Estimated: `10256 + k * (2579 ±0)` - // Minimum execution time: 480_320_000 picoseconds. - Weight::from_parts(250_987_824, 10256) - // Standard Error: 56_710 - .saturating_add(Weight::from_parts(48_825_380, 0).saturating_mul(k.into())) + // Minimum execution time: 222_000_000 picoseconds. + Weight::from_parts(135_764_772, 10256) + // Standard Error: 49_814 + .saturating_add(Weight::from_parts(23_501_234, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(49_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into()))) - .saturating_add(T::DbWeight::get().writes(52_u64)) + .saturating_add(T::DbWeight::get().writes(53_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into()))) .saturating_add(Weight::from_parts(0, 2579).saturating_mul(k.into())) } @@ -2044,10 +2084,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1501 + k * (53 ±0)` // Estimated: `6148 + k * (2529 ±0)` - // Minimum execution time: 89_272_000 picoseconds. - Weight::from_parts(79_136_631, 6148) - // Standard Error: 7_622 - .saturating_add(Weight::from_parts(1_641_271, 0).saturating_mul(k.into())) + // Minimum execution time: 41_000_000 picoseconds. + Weight::from_parts(49_310_804, 6148) + // Standard Error: 5_811 + .saturating_add(Weight::from_parts(865_763, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) @@ -2062,8 +2102,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `659` // Estimated: `9074` - // Minimum execution time: 23_875_000 picoseconds. - Weight::from_parts(25_027_000, 9074) + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(12_000_000, 9074) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -2081,19 +2121,27 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastUpdate` (r:1 w:1) /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) + /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::BlocksSinceLastStep` (r:1 w:0) + /// Proof: `SubtensorModule::BlocksSinceLastStep` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TimelockedWeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::TimelockedWeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:1 w:0) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) fn commit_timelocked_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1070` - // Estimated: `4535` - // Minimum execution time: 71_556_000 picoseconds. - Weight::from_parts(73_198_000, 4535) - .saturating_add(T::DbWeight::get().reads(10_u64)) + // Measured: `1248` + // Estimated: `4713` + // Minimum execution time: 39_000_000 picoseconds. + Weight::from_parts(40_000_000, 4713) + .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -2108,8 +2156,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `809` // Estimated: `4274` - // Minimum execution time: 31_547_000 picoseconds. - Weight::from_parts(32_238_000, 4274) + // Minimum execution time: 14_000_000 picoseconds. + Weight::from_parts(15_000_000, 4274) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -2125,8 +2173,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `476` // Estimated: `3941` - // Minimum execution time: 15_273_000 picoseconds. - Weight::from_parts(16_074_000, 3941) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(8_000_000, 3941) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -2156,8 +2204,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1935` // Estimated: `7875` - // Minimum execution time: 139_456_000 picoseconds. - Weight::from_parts(141_309_000, 7875) + // Minimum execution time: 59_000_000 picoseconds. + Weight::from_parts(60_000_000, 7875) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -2167,8 +2215,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_023_000 picoseconds. - Weight::from_parts(2_303_000, 0) + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::RootClaimableThreshold` (r:0 w:1) @@ -2177,8 +2225,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_567_000 picoseconds. - Weight::from_parts(5_117_000, 0) + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(2_000_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -2191,8 +2239,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `899` // Estimated: `4364` - // Minimum execution time: 24_225_000 picoseconds. - Weight::from_parts(25_578_000, 4364) + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(12_000_000, 4364) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -2264,8 +2312,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2229` // Estimated: `8727` - // Minimum execution time: 990_125_000 picoseconds. - Weight::from_parts(995_442_000, 8727) + // Minimum execution time: 408_000_000 picoseconds. + Weight::from_parts(415_000_000, 8727) .saturating_add(T::DbWeight::get().reads(33_u64)) .saturating_add(T::DbWeight::get().writes(17_u64)) } @@ -2275,8 +2323,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_013_000 picoseconds. - Weight::from_parts(2_173_000, 0) + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -2317,8 +2365,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1715` // Estimated: `7655` - // Minimum execution time: 114_670_000 picoseconds. - Weight::from_parts(116_542_000, 7655) + // Minimum execution time: 51_000_000 picoseconds. + Weight::from_parts(55_000_000, 7655) .saturating_add(T::DbWeight::get().reads(17_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -2348,8 +2396,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1399` // Estimated: `7339` - // Minimum execution time: 154_609_000 picoseconds. - Weight::from_parts(156_442_000, 7339) + // Minimum execution time: 69_000_000 picoseconds. + Weight::from_parts(174_000_000, 7339) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -2363,15 +2411,13 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `950` // Estimated: `4415` - // Minimum execution time: 697_391_000 picoseconds. - Weight::from_parts(712_594_000, 4415) + // Minimum execution time: 268_000_000 picoseconds. + Weight::from_parts(274_000_000, 4415) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::SubnetOwner` (r:1 w:0) /// Proof: `SubtensorModule::SubnetOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) - /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:1) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) @@ -2384,11 +2430,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::TransactionKeyLastBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_tempo() -> Weight { // Proof Size summary in bytes: - // Measured: `1015` - // Estimated: `4480` - // Minimum execution time: 34_000_000 picoseconds. - Weight::from_parts(35_000_000, 4480) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Measured: `975` + // Estimated: `4440` + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(23_000_000, 4440) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `SubtensorModule::SubnetOwner` (r:1 w:0) @@ -2409,10 +2455,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::ActivityCutoffFactorMilli` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_activity_cutoff_factor() -> Weight { // Proof Size summary in bytes: - // Measured: `889` - // Estimated: `4354` - // Minimum execution time: 29_000_000 picoseconds. - Weight::from_parts(31_000_000, 4354) + // Measured: `899` + // Estimated: `4364` + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 4364) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -2422,22 +2468,126 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:1) /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::OwnerHyperparamRateLimit` (r:1 w:0) - /// Proof: `SubtensorModule::OwnerHyperparamRateLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::AdminFreezeWindow` (r:1 w:0) + /// Proof: `SubtensorModule::AdminFreezeWindow` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::OwnerHyperparamRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::OwnerHyperparamRateLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastRateLimitedBlock` (r:1 w:1) /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::AdminFreezeWindow` (r:1 w:0) - /// Proof: `SubtensorModule::AdminFreezeWindow` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn trigger_epoch() -> Weight { // Proof Size summary in bytes: - // Measured: `853` - // Estimated: `4318` + // Measured: `982` + // Estimated: `4447` + // Minimum execution time: 19_000_000 picoseconds. + Weight::from_parts(20_000_000, 4447) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapAnnouncements` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ColdkeySwapDisputes` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapDisputes` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_coldkey_swap_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `733` + // Estimated: `4198` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 4198) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: `SubtensorModule::SubnetOwnerHotkey` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetOwnerHotkey` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TaoWeight` (r:1 w:0) + /// Proof: `SubtensorModule::TaoWeight` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TotalHotkeyAlpha` (r:2 w:0) + /// Proof: `SubtensorModule::TotalHotkeyAlpha` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ParentKeys` (r:1 w:0) + /// Proof: `SubtensorModule::ParentKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ChildKeys` (r:1 w:0) + /// Proof: `SubtensorModule::ChildKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::StakeThreshold` (r:1 w:0) + /// Proof: `SubtensorModule::StakeThreshold` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::WeightCommits` (r:1 w:0) + /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Tempo` (r:1 w:0) + /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) + /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_weights_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `1731` + // Estimated: `7671` // Minimum execution time: 25_000_000 picoseconds. - Weight::from_parts(28_000_000, 4318) + Weight::from_parts(26_000_000, 7671) + .saturating_add(T::DbWeight::get().reads(11_u64)) + } + /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) + /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) + /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::MechanismCountCurrent` (r:1 w:0) + /// Proof: `SubtensorModule::MechanismCountCurrent` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Keys` (r:1 w:0) + /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastUpdate` (r:1 w:0) + /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::WeightsSetRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::WeightsSetRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_rate_limits_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `1019` + // Estimated: `4484` + // Minimum execution time: 17_000_000 picoseconds. + Weight::from_parts(18_000_000, 4484) .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `SubtensorModule::MinDelegateTake` (r:1 w:0) + /// Proof: `SubtensorModule::MinDelegateTake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::MaxDelegateTake` (r:1 w:0) + /// Proof: `SubtensorModule::MaxDelegateTake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Owner` (r:1 w:0) + /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_delegate_take_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `721` + // Estimated: `4186` + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(8_000_000, 4186) + .saturating_add(T::DbWeight::get().reads(3_u64)) + } + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Axons` (r:1 w:0) + /// Proof: `SubtensorModule::Axons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_serving_endpoints_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `647` + // Estimated: `4112` + // Minimum execution time: 9_000_000 picoseconds. + Weight::from_parts(9_000_000, 4112) + .saturating_add(T::DbWeight::get().reads(3_u64)) + } + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::AssociatedEvmAddress` (r:1 w:0) + /// Proof: `SubtensorModule::AssociatedEvmAddress` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_evm_key_association_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `652` + // Estimated: `4117` + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(7_000_000, 4117) + .saturating_add(T::DbWeight::get().reads(2_u64)) } } @@ -2519,10 +2669,10 @@ impl WeightInfo for () { /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) fn register() -> Weight { // Proof Size summary in bytes: - // Measured: `1837` + // Measured: `1865` // Estimated: `6148` - // Minimum execution time: 340_604_000 picoseconds. - Weight::from_parts(344_520_000, 6148) + // Minimum execution time: 148_000_000 picoseconds. + Weight::from_parts(155_000_000, 6148) .saturating_add(RocksDbWeight::get().reads(34_u64)) .saturating_add(RocksDbWeight::get().writes(29_u64)) } @@ -2562,10 +2712,10 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `188792` - // Estimated: `10327382` - // Minimum execution time: 16_142_608_000 picoseconds. - Weight::from_parts(16_400_997_000, 10327382) + // Measured: `188820` + // Estimated: `10327410` + // Minimum execution time: 6_739_000_000 picoseconds. + Weight::from_parts(6_870_000_000, 10327410) .saturating_add(RocksDbWeight::get().reads(4112_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2635,39 +2785,39 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2226` // Estimated: `8727` - // Minimum execution time: 665_334_000 picoseconds. - Weight::from_parts(685_664_000, 8727) + // Minimum execution time: 280_000_000 picoseconds. + Weight::from_parts(284_000_000, 8727) .saturating_add(RocksDbWeight::get().reads(32_u64)) .saturating_add(RocksDbWeight::get().writes(16_u64)) } - /// Storage: `SubtensorModule::IsNetworkMember` (r:2 w:0) - /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Axons` (r:1 w:1) /// Proof: `SubtensorModule::Axons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) fn serve_axon() -> Weight { // Proof Size summary in bytes: - // Measured: `801` - // Estimated: `6741` - // Minimum execution time: 31_927_000 picoseconds. - Weight::from_parts(33_199_000, 6741) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `713` + // Estimated: `4178` + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(16_000_000, 4178) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `SubtensorModule::IsNetworkMember` (r:2 w:0) - /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Prometheus` (r:1 w:1) /// Proof: `SubtensorModule::Prometheus` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) fn serve_prometheus() -> Weight { // Proof Size summary in bytes: - // Measured: `774` - // Estimated: `6714` - // Minimum execution time: 28_011_000 picoseconds. - Weight::from_parts(29_073_000, 6714) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `812` + // Estimated: `4277` + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(16_000_000, 4277) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -2746,10 +2896,10 @@ impl WeightInfo for () { /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) fn burned_register() -> Weight { // Proof Size summary in bytes: - // Measured: `1770` + // Measured: `1798` // Estimated: `6148` - // Minimum execution time: 337_589_000 picoseconds. - Weight::from_parts(341_856_000, 6148) + // Minimum execution time: 149_000_000 picoseconds. + Weight::from_parts(154_000_000, 6148) .saturating_add(RocksDbWeight::get().reads(34_u64)) .saturating_add(RocksDbWeight::get().writes(29_u64)) } @@ -2799,10 +2949,10 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) fn root_register() -> Weight { // Proof Size summary in bytes: - // Measured: `1482` - // Estimated: `4947` - // Minimum execution time: 100_028_000 picoseconds. - Weight::from_parts(102_953_000, 4947) + // Measured: `1516` + // Estimated: `4981` + // Minimum execution time: 46_000_000 picoseconds. + Weight::from_parts(47_000_000, 4981) .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().writes(16_u64)) } @@ -2900,6 +3050,8 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaOut` (r:0 w:1) /// Proof: `SubtensorModule::SubnetAlphaOut` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:0 w:1) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:0 w:1) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Uids` (r:0 w:1) @@ -2920,10 +3072,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1532` // Estimated: `9947` - // Minimum execution time: 266_053_000 picoseconds. - Weight::from_parts(272_392_000, 9947) + // Minimum execution time: 123_000_000 picoseconds. + Weight::from_parts(125_000_000, 9947) .saturating_add(RocksDbWeight::get().reads(40_u64)) - .saturating_add(RocksDbWeight::get().writes(47_u64)) + .saturating_add(RocksDbWeight::get().writes(48_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -2937,27 +3089,35 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastUpdate` (r:1 w:1) /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) - /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) + /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::BlocksSinceLastStep` (r:1 w:0) + /// Proof: `SubtensorModule::BlocksSinceLastStep` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:1 w:0) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) fn commit_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1071` - // Estimated: `4536` - // Minimum execution time: 57_885_000 picoseconds. - Weight::from_parts(58_817_000, 4536) - .saturating_add(RocksDbWeight::get().reads(10_u64)) + // Measured: `1249` + // Estimated: `4714` + // Minimum execution time: 30_000_000 picoseconds. + Weight::from_parts(31_000_000, 4714) + .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) @@ -2992,11 +3152,11 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn reveal_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1589` - // Estimated: `7529` - // Minimum execution time: 105_065_000 picoseconds. - Weight::from_parts(107_229_000, 7529) - .saturating_add(RocksDbWeight::get().reads(18_u64)) + // Measured: `1650` + // Estimated: `7590` + // Minimum execution time: 49_000_000 picoseconds. + Weight::from_parts(52_000_000, 7590) + .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::TxChildkeyTakeRateLimit` (r:0 w:1) @@ -3005,8 +3165,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_036_000 picoseconds. - Weight::from_parts(4_397_000, 0) + // Minimum execution time: 2_000_000 picoseconds. + Weight::from_parts(2_000_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -3027,8 +3187,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1033` // Estimated: `4498` - // Minimum execution time: 51_045_000 picoseconds. - Weight::from_parts(51_967_000, 4498) + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(25_000_000, 4498) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -3044,8 +3204,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `694` // Estimated: `4159` - // Minimum execution time: 43_204_000 picoseconds. - Weight::from_parts(45_056_000, 4159) + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(23_000_000, 4159) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3073,6 +3233,8 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::TotalHotkeyShares` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalHotkeySharesV2` (r:2 w:2) /// Proof: `SubtensorModule::TotalHotkeySharesV2` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::StakingColdkeys` (r:1 w:0) + /// Proof: `SubtensorModule::StakingColdkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::OwnedHotkeys` (r:2 w:2) /// Proof: `SubtensorModule::OwnedHotkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::UnlockRate` (r:1 w:0) @@ -3091,9 +3253,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2110` // Estimated: `13000` - // Minimum execution time: 285_883_000 picoseconds. - Weight::from_parts(289_268_000, 13000) - .saturating_add(RocksDbWeight::get().reads(36_u64)) + // Minimum execution time: 128_000_000 picoseconds. + Weight::from_parts(132_000_000, 13000) + .saturating_add(RocksDbWeight::get().reads(37_u64)) .saturating_add(RocksDbWeight::get().writes(15_u64)) } /// Storage: `System::Account` (r:2 w:2) @@ -3122,6 +3284,8 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::TotalHotkeyShares` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalHotkeySharesV2` (r:2 w:2) /// Proof: `SubtensorModule::TotalHotkeySharesV2` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::StakingColdkeys` (r:1 w:0) + /// Proof: `SubtensorModule::StakingColdkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::OwnedHotkeys` (r:2 w:2) /// Proof: `SubtensorModule::OwnedHotkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::UnlockRate` (r:1 w:0) @@ -3142,9 +3306,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2166` // Estimated: `13056` - // Minimum execution time: 308_517_000 picoseconds. - Weight::from_parts(314_044_000, 13056) - .saturating_add(RocksDbWeight::get().reads(36_u64)) + // Minimum execution time: 138_000_000 picoseconds. + Weight::from_parts(144_000_000, 13056) + .saturating_add(RocksDbWeight::get().reads(37_u64)) .saturating_add(RocksDbWeight::get().writes(19_u64)) } /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) @@ -3155,8 +3319,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `665` // Estimated: `4130` - // Minimum execution time: 20_170_000 picoseconds. - Weight::from_parts(20_820_000, 4130) + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(11_000_000, 4130) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -3168,8 +3332,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `613` // Estimated: `4078` - // Minimum execution time: 16_435_000 picoseconds. - Weight::from_parts(17_065_000, 4078) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 4078) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -3181,14 +3345,16 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_750_000 picoseconds. - Weight::from_parts(7_190_000, 0) + // Minimum execution time: 3_000_000 picoseconds. + Weight::from_parts(4_000_000, 0) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) @@ -3223,11 +3389,11 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn batch_reveal_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `2094` - // Estimated: `8034` - // Minimum execution time: 414_593_000 picoseconds. - Weight::from_parts(422_245_000, 8034) - .saturating_add(RocksDbWeight::get().reads(18_u64)) + // Measured: `2155` + // Estimated: `8095` + // Minimum execution time: 191_000_000 picoseconds. + Weight::from_parts(197_000_000, 8095) + .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -3260,8 +3426,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1754` // Estimated: `5219` - // Minimum execution time: 173_126_000 picoseconds. - Weight::from_parts(174_428_000, 5219) + // Minimum execution time: 74_000_000 picoseconds. + Weight::from_parts(75_000_000, 5219) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -3293,8 +3459,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1754` // Estimated: `5219` - // Minimum execution time: 167_228_000 picoseconds. - Weight::from_parts(169_080_000, 5219) + // Minimum execution time: 72_000_000 picoseconds. + Weight::from_parts(73_000_000, 5219) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -3314,8 +3480,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1118` // Estimated: `4583` - // Minimum execution time: 37_305_000 picoseconds. - Weight::from_parts(38_226_000, 4583) + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 4583) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -3385,8 +3551,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2226` // Estimated: `8727` - // Minimum execution time: 862_916_000 picoseconds. - Weight::from_parts(876_506_000, 8727) + // Minimum execution time: 357_000_000 picoseconds. + Weight::from_parts(371_000_000, 8727) .saturating_add(RocksDbWeight::get().reads(32_u64)) .saturating_add(RocksDbWeight::get().writes(16_u64)) } @@ -3422,8 +3588,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1979` // Estimated: `7919` - // Minimum execution time: 218_613_000 picoseconds. - Weight::from_parts(219_955_000, 7919) + // Minimum execution time: 95_000_000 picoseconds. + Weight::from_parts(96_000_000, 7919) .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -3479,8 +3645,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2142` // Estimated: `10557` - // Minimum execution time: 559_437_000 picoseconds. - Weight::from_parts(573_518_000, 10557) + // Minimum execution time: 236_000_000 picoseconds. + Weight::from_parts(238_000_000, 10557) .saturating_add(RocksDbWeight::get().reads(28_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -3534,8 +3700,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2176` // Estimated: `10591` - // Minimum execution time: 739_182_000 picoseconds. - Weight::from_parts(755_287_000, 10591) + // Minimum execution time: 308_000_000 picoseconds. + Weight::from_parts(315_000_000, 10591) .saturating_add(RocksDbWeight::get().reads(27_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -3607,8 +3773,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2662` // Estimated: `11077` - // Minimum execution time: 949_273_000 picoseconds. - Weight::from_parts(964_857_000, 11077) + // Minimum execution time: 397_000_000 picoseconds. + Weight::from_parts(404_000_000, 11077) .saturating_add(RocksDbWeight::get().reads(47_u64)) .saturating_add(RocksDbWeight::get().writes(24_u64)) } @@ -3648,8 +3814,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1988` // Estimated: `7928` - // Minimum execution time: 250_861_000 picoseconds. - Weight::from_parts(253_195_000, 7928) + // Minimum execution time: 108_000_000 picoseconds. + Weight::from_parts(109_000_000, 7928) .saturating_add(RocksDbWeight::get().reads(18_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -3721,8 +3887,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2505` // Estimated: `10920` - // Minimum execution time: 728_698_000 picoseconds. - Weight::from_parts(746_774_000, 10920) + // Minimum execution time: 312_000_000 picoseconds. + Weight::from_parts(317_000_000, 10920) .saturating_add(RocksDbWeight::get().reads(47_u64)) .saturating_add(RocksDbWeight::get().writes(24_u64)) } @@ -3738,23 +3904,31 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastUpdate` (r:1 w:1) /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) - /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) + /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::BlocksSinceLastStep` (r:1 w:0) + /// Proof: `SubtensorModule::BlocksSinceLastStep` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:1 w:0) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::WeightsSetRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::WeightsSetRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) + /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) fn batch_commit_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1122` - // Estimated: `4587` - // Minimum execution time: 123_562_000 picoseconds. - Weight::from_parts(125_566_000, 4587) - .saturating_add(RocksDbWeight::get().reads(11_u64)) + // Measured: `1300` + // Estimated: `4765` + // Minimum execution time: 67_000_000 picoseconds. + Weight::from_parts(67_000_000, 4765) + .saturating_add(RocksDbWeight::get().reads(15_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) @@ -3791,10 +3965,10 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Weights` (`max_values`: None, `max_size`: None, mode: `Measured`) fn batch_set_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1426` - // Estimated: `7366` - // Minimum execution time: 97_624_000 picoseconds. - Weight::from_parts(100_468_000, 7366) + // Measured: `1455` + // Estimated: `7395` + // Minimum execution time: 45_000_000 picoseconds. + Weight::from_parts(46_000_000, 7395) .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -3810,8 +3984,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `830` // Estimated: `4295` - // Minimum execution time: 26_830_000 picoseconds. - Weight::from_parts(27_561_000, 4295) + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(14_000_000, 4295) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -3829,8 +4003,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `923` // Estimated: `4388` - // Minimum execution time: 33_029_000 picoseconds. - Weight::from_parts(34_211_000, 4388) + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(17_000_000, 4388) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -3928,6 +4102,8 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaOut` (r:0 w:1) /// Proof: `SubtensorModule::SubnetAlphaOut` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:0 w:1) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:0 w:1) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Uids` (r:0 w:1) @@ -3948,24 +4124,24 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1468` // Estimated: `9883` - // Minimum execution time: 266_604_000 picoseconds. - Weight::from_parts(276_799_000, 9883) + // Minimum execution time: 121_000_000 picoseconds. + Weight::from_parts(123_000_000, 9883) .saturating_add(RocksDbWeight::get().reads(39_u64)) - .saturating_add(RocksDbWeight::get().writes(46_u64)) + .saturating_add(RocksDbWeight::get().writes(47_u64)) } - /// Storage: `SubtensorModule::IsNetworkMember` (r:2 w:0) - /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Axons` (r:1 w:1) /// Proof: `SubtensorModule::Axons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) fn serve_axon_tls() -> Weight { // Proof Size summary in bytes: - // Measured: `772` - // Estimated: `6712` - // Minimum execution time: 31_506_000 picoseconds. - Weight::from_parts(32_528_000, 6712) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `684` + // Estimated: `4149` + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(13_000_000, 4149) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::OwnedHotkeys` (r:1 w:0) @@ -3978,8 +4154,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `889` // Estimated: `6829` - // Minimum execution time: 29_043_000 picoseconds. - Weight::from_parts(30_816_000, 6829) + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(14_000_000, 6829) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -3991,12 +4167,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `595` // Estimated: `4060` - // Minimum execution time: 15_503_000 picoseconds. - Weight::from_parts(16_204_000, 4060) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(8_000_000, 4060) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `SubtensorModule::Owner` (r:1 w:2) + /// Storage: `SubtensorModule::Owner` (r:2 w:2) /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastRateLimitedBlock` (r:4 w:7) /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -4008,14 +4184,20 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::RootClaimable` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalHotkeyAlpha` (r:9 w:8) /// Proof: `SubtensorModule::TotalHotkeyAlpha` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::RootClaimed` (r:1 w:0) + /// Proof: `SubtensorModule::RootClaimed` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworksAdded` (r:6 w:0) + /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ChildKeys` (r:10 w:10) + /// Proof: `SubtensorModule::ChildKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastHotkeySwapOnNetuid` (r:4 w:4) + /// Proof: `SubtensorModule::LastHotkeySwapOnNetuid` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalIssuance` (r:1 w:1) /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Alpha` (r:9 w:0) /// Proof: `SubtensorModule::Alpha` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::AlphaV2` (r:9 w:8) /// Proof: `SubtensorModule::AlphaV2` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::NetworksAdded` (r:6 w:0) - /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetOwnerHotkey` (r:5 w:0) /// Proof: `SubtensorModule::SubnetOwnerHotkey` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::HotkeyLock` (r:5 w:0) @@ -4024,8 +4206,8 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::DecayingHotkeyLock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::OwnedHotkeys` (r:1 w:1) /// Proof: `SubtensorModule::OwnedHotkeys` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::ChildKeys` (r:10 w:10) - /// Proof: `SubtensorModule::ChildKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ChildkeyTake` (r:5 w:0) + /// Proof: `SubtensorModule::ChildkeyTake` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ParentKeys` (r:10 w:10) /// Proof: `SubtensorModule::ParentKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::PendingChildKeys` (r:10 w:0) @@ -4066,12 +4248,12 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) fn swap_hotkey() -> Weight { // Proof Size summary in bytes: - // Measured: `3131` - // Estimated: `28871` - // Minimum execution time: 1_193_554_000 picoseconds. - Weight::from_parts(1_201_736_000, 28871) - .saturating_add(RocksDbWeight::get().reads(171_u64)) - .saturating_add(RocksDbWeight::get().writes(95_u64)) + // Measured: `3172` + // Estimated: `28912` + // Minimum execution time: 529_000_000 picoseconds. + Weight::from_parts(543_000_000, 28912) + .saturating_add(RocksDbWeight::get().reads(182_u64)) + .saturating_add(RocksDbWeight::get().writes(99_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:1) /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -4083,8 +4265,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `818` // Estimated: `4283` - // Minimum execution time: 23_084_000 picoseconds. - Weight::from_parts(23_836_000, 4283) + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(11_000_000, 4283) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -4098,8 +4280,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `774` // Estimated: `9189` - // Minimum execution time: 24_587_000 picoseconds. - Weight::from_parts(25_608_000, 9189) + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(13_000_000, 9189) .saturating_add(RocksDbWeight::get().reads(6_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -4160,8 +4342,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2235` // Estimated: `11306` - // Minimum execution time: 695_268_000 picoseconds. - Weight::from_parts(708_618_000, 11306) + // Minimum execution time: 296_000_000 picoseconds. + Weight::from_parts(302_000_000, 11306) .saturating_add(RocksDbWeight::get().reads(43_u64)) .saturating_add(RocksDbWeight::get().writes(25_u64)) } @@ -4215,8 +4397,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2176` // Estimated: `10591` - // Minimum execution time: 763_548_000 picoseconds. - Weight::from_parts(778_691_000, 10591) + // Minimum execution time: 317_000_000 picoseconds. + Weight::from_parts(323_000_000, 10591) .saturating_add(RocksDbWeight::get().reads(27_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -4330,6 +4512,8 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaOut` (r:0 w:1) /// Proof: `SubtensorModule::SubnetAlphaOut` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:0 w:1) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:0 w:1) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Uids` (r:0 w:1) @@ -4353,13 +4537,13 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1835 + k * (44 ±0)` // Estimated: `10256 + k * (2579 ±0)` - // Minimum execution time: 480_320_000 picoseconds. - Weight::from_parts(250_987_824, 10256) - // Standard Error: 56_710 - .saturating_add(Weight::from_parts(48_825_380, 0).saturating_mul(k.into())) + // Minimum execution time: 222_000_000 picoseconds. + Weight::from_parts(135_764_772, 10256) + // Standard Error: 49_814 + .saturating_add(Weight::from_parts(23_501_234, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(49_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(k.into()))) - .saturating_add(RocksDbWeight::get().writes(52_u64)) + .saturating_add(RocksDbWeight::get().writes(53_u64)) .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(k.into()))) .saturating_add(Weight::from_parts(0, 2579).saturating_mul(k.into())) } @@ -4386,10 +4570,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1501 + k * (53 ±0)` // Estimated: `6148 + k * (2529 ±0)` - // Minimum execution time: 89_272_000 picoseconds. - Weight::from_parts(79_136_631, 6148) - // Standard Error: 7_622 - .saturating_add(Weight::from_parts(1_641_271, 0).saturating_mul(k.into())) + // Minimum execution time: 41_000_000 picoseconds. + Weight::from_parts(49_310_804, 6148) + // Standard Error: 5_811 + .saturating_add(Weight::from_parts(865_763, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) @@ -4404,8 +4588,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `659` // Estimated: `9074` - // Minimum execution time: 23_875_000 picoseconds. - Weight::from_parts(25_027_000, 9074) + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(12_000_000, 9074) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -4423,19 +4607,27 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastUpdate` (r:1 w:1) /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) + /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::BlocksSinceLastStep` (r:1 w:0) + /// Proof: `SubtensorModule::BlocksSinceLastStep` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TimelockedWeightCommits` (r:1 w:1) /// Proof: `SubtensorModule::TimelockedWeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetworkN` (r:1 w:0) /// Proof: `SubtensorModule::SubnetworkN` (`max_values`: None, `max_size`: None, mode: `Measured`) fn commit_timelocked_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `1070` - // Estimated: `4535` - // Minimum execution time: 71_556_000 picoseconds. - Weight::from_parts(73_198_000, 4535) - .saturating_add(RocksDbWeight::get().reads(10_u64)) + // Measured: `1248` + // Estimated: `4713` + // Minimum execution time: 39_000_000 picoseconds. + Weight::from_parts(40_000_000, 4713) + .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -4450,8 +4642,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `809` // Estimated: `4274` - // Minimum execution time: 31_547_000 picoseconds. - Weight::from_parts(32_238_000, 4274) + // Minimum execution time: 14_000_000 picoseconds. + Weight::from_parts(15_000_000, 4274) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -4467,8 +4659,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `476` // Estimated: `3941` - // Minimum execution time: 15_273_000 picoseconds. - Weight::from_parts(16_074_000, 3941) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(8_000_000, 3941) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -4498,8 +4690,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1935` // Estimated: `7875` - // Minimum execution time: 139_456_000 picoseconds. - Weight::from_parts(141_309_000, 7875) + // Minimum execution time: 59_000_000 picoseconds. + Weight::from_parts(60_000_000, 7875) .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -4509,8 +4701,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_023_000 picoseconds. - Weight::from_parts(2_303_000, 0) + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::RootClaimableThreshold` (r:0 w:1) @@ -4519,8 +4711,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_567_000 picoseconds. - Weight::from_parts(5_117_000, 0) + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(2_000_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -4533,8 +4725,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `899` // Estimated: `4364` - // Minimum execution time: 24_225_000 picoseconds. - Weight::from_parts(25_578_000, 4364) + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(12_000_000, 4364) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -4606,8 +4798,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2229` // Estimated: `8727` - // Minimum execution time: 990_125_000 picoseconds. - Weight::from_parts(995_442_000, 8727) + // Minimum execution time: 408_000_000 picoseconds. + Weight::from_parts(415_000_000, 8727) .saturating_add(RocksDbWeight::get().reads(33_u64)) .saturating_add(RocksDbWeight::get().writes(17_u64)) } @@ -4617,8 +4809,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_013_000 picoseconds. - Weight::from_parts(2_173_000, 0) + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -4659,8 +4851,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1715` // Estimated: `7655` - // Minimum execution time: 114_670_000 picoseconds. - Weight::from_parts(116_542_000, 7655) + // Minimum execution time: 51_000_000 picoseconds. + Weight::from_parts(55_000_000, 7655) .saturating_add(RocksDbWeight::get().reads(17_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -4690,8 +4882,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1399` // Estimated: `7339` - // Minimum execution time: 154_609_000 picoseconds. - Weight::from_parts(156_442_000, 7339) + // Minimum execution time: 69_000_000 picoseconds. + Weight::from_parts(174_000_000, 7339) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -4705,15 +4897,13 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `950` // Estimated: `4415` - // Minimum execution time: 697_391_000 picoseconds. - Weight::from_parts(712_594_000, 4415) + // Minimum execution time: 268_000_000 picoseconds. + Weight::from_parts(274_000_000, 4415) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SubtensorModule::SubnetOwner` (r:1 w:0) /// Proof: `SubtensorModule::SubnetOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) - /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:1) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:0) @@ -4726,11 +4916,11 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::TransactionKeyLastBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_tempo() -> Weight { // Proof Size summary in bytes: - // Measured: `1015` - // Estimated: `4480` - // Minimum execution time: 34_000_000 picoseconds. - Weight::from_parts(35_000_000, 4480) - .saturating_add(RocksDbWeight::get().reads(7_u64)) + // Measured: `975` + // Estimated: `4440` + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(23_000_000, 4440) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `SubtensorModule::SubnetOwner` (r:1 w:0) @@ -4751,10 +4941,10 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::ActivityCutoffFactorMilli` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_activity_cutoff_factor() -> Weight { // Proof Size summary in bytes: - // Measured: `889` - // Estimated: `4354` - // Minimum execution time: 29_000_000 picoseconds. - Weight::from_parts(31_000_000, 4354) + // Measured: `899` + // Estimated: `4364` + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 4364) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -4764,21 +4954,125 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::PendingEpochAt` (r:1 w:1) /// Proof: `SubtensorModule::PendingEpochAt` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::OwnerHyperparamRateLimit` (r:1 w:0) - /// Proof: `SubtensorModule::OwnerHyperparamRateLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::AdminFreezeWindow` (r:1 w:0) + /// Proof: `SubtensorModule::AdminFreezeWindow` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Tempo` (r:1 w:0) /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastEpochBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastEpochBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::OwnerHyperparamRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::OwnerHyperparamRateLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::LastRateLimitedBlock` (r:1 w:1) /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::AdminFreezeWindow` (r:1 w:0) - /// Proof: `SubtensorModule::AdminFreezeWindow` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn trigger_epoch() -> Weight { // Proof Size summary in bytes: - // Measured: `853` - // Estimated: `4318` + // Measured: `982` + // Estimated: `4447` + // Minimum execution time: 19_000_000 picoseconds. + Weight::from_parts(20_000_000, 4447) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapAnnouncements` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ColdkeySwapDisputes` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapDisputes` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_coldkey_swap_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `733` + // Estimated: `4198` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 4198) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: `SubtensorModule::SubnetOwnerHotkey` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetOwnerHotkey` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TaoWeight` (r:1 w:0) + /// Proof: `SubtensorModule::TaoWeight` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TotalHotkeyAlpha` (r:2 w:0) + /// Proof: `SubtensorModule::TotalHotkeyAlpha` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ParentKeys` (r:1 w:0) + /// Proof: `SubtensorModule::ParentKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ChildKeys` (r:1 w:0) + /// Proof: `SubtensorModule::ChildKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::StakeThreshold` (r:1 w:0) + /// Proof: `SubtensorModule::StakeThreshold` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::WeightCommits` (r:1 w:0) + /// Proof: `SubtensorModule::WeightCommits` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetEpochIndex` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetEpochIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Tempo` (r:1 w:0) + /// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::RevealPeriodEpochs` (r:1 w:0) + /// Proof: `SubtensorModule::RevealPeriodEpochs` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_weights_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `1731` + // Estimated: `7671` // Minimum execution time: 25_000_000 picoseconds. - Weight::from_parts(28_000_000, 4318) + Weight::from_parts(26_000_000, 7671) + .saturating_add(RocksDbWeight::get().reads(11_u64)) + } + /// Storage: `SubtensorModule::CommitRevealWeightsEnabled` (r:1 w:0) + /// Proof: `SubtensorModule::CommitRevealWeightsEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) + /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::MechanismCountCurrent` (r:1 w:0) + /// Proof: `SubtensorModule::MechanismCountCurrent` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Keys` (r:1 w:0) + /// Proof: `SubtensorModule::Keys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastUpdate` (r:1 w:0) + /// Proof: `SubtensorModule::LastUpdate` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::WeightsSetRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::WeightsSetRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_rate_limits_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `1019` + // Estimated: `4484` + // Minimum execution time: 17_000_000 picoseconds. + Weight::from_parts(18_000_000, 4484) .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `SubtensorModule::MinDelegateTake` (r:1 w:0) + /// Proof: `SubtensorModule::MinDelegateTake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::MaxDelegateTake` (r:1 w:0) + /// Proof: `SubtensorModule::MaxDelegateTake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Owner` (r:1 w:0) + /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_delegate_take_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `721` + // Estimated: `4186` + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(8_000_000, 4186) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + } + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::Axons` (r:1 w:0) + /// Proof: `SubtensorModule::Axons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::ServingRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::ServingRateLimit` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_serving_endpoints_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `647` + // Estimated: `4112` + // Minimum execution time: 9_000_000 picoseconds. + Weight::from_parts(9_000_000, 4112) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + } + /// Storage: `SubtensorModule::Uids` (r:1 w:0) + /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::AssociatedEvmAddress` (r:1 w:0) + /// Proof: `SubtensorModule::AssociatedEvmAddress` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn check_evm_key_association_extension() -> Weight { + // Proof Size summary in bytes: + // Measured: `652` + // Estimated: `4117` + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(7_000_000, 4117) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } } diff --git a/precompiles/src/extensions.rs b/precompiles/src/extensions.rs index b98fcfb515..984b70a91b 100644 --- a/precompiles/src/extensions.rs +++ b/precompiles/src/extensions.rs @@ -3,26 +3,16 @@ extern crate alloc; use alloc::format; use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo}; -use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_admin_utils::{PrecompileEnable, PrecompileEnum}; use pallet_evm::{ AddressMapping, BalanceConverter, EvmBalance, ExitError, GasWeightMapping, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult, }; -use pallet_subtensor::SubtensorTransactionExtension; use precompile_utils::EvmResult; use precompile_utils::prelude::RuntimeHelper; -use scale_info::TypeInfo; use sp_core::{H160, U256, blake2_256}; -use sp_runtime::{ - DispatchResult, - traits::{ - AsSystemOriginSigner, Dispatchable, ExtensionPostDispatchWeightHandler, - TransactionExtension, TxBaseImplication, - }, - transaction_validity::{TransactionSource, TransactionValidityError}, -}; +use sp_runtime::traits::{Dispatchable, ExtensionPostDispatchWeightHandler}; use sp_std::vec::Vec; use subtensor_runtime_common::with_evm_context; @@ -74,30 +64,17 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { ) -> EvmResult<()> where R: frame_system::Config - + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + pallet_shield::Config - + pallet_subtensor_proxy::Config - + Send - + Sync - + TypeInfo, + + pallet_subtensor_proxy::Config, ::RuntimeCall: From, - ::RuntimeCall: GetDispatchInfo - + Dispatchable - + IsSubType> - + IsSubType> - + IsSubType> - + IsSubType>, - ::RuntimeOrigin: - From> + AsSystemOriginSigner + Clone, + ::RuntimeCall: + GetDispatchInfo + Dispatchable, + ::RuntimeOrigin: From> + Clone, { let call = ::RuntimeCall::from(call); - let mut info = GetDispatchInfo::get_dispatch_info(&call); - let subtensor_extension = SubtensorTransactionExtension::::new(); - info.extension_weight = info - .extension_weight - .saturating_add(subtensor_extension.weight(&call)); + let info = GetDispatchInfo::get_dispatch_info(&call); let target_gas = self.gas_limit(); if let Some(gas) = target_gas { @@ -117,29 +94,10 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { )?; let origin = ::RuntimeOrigin::from(origin); - let (_, val, origin) = subtensor_extension - .validate( - origin, - &call, - &info, - 0, - (), - &TxBaseImplication(()), - TransactionSource::External, - ) - .map_err(extension_error)?; - subtensor_extension - .prepare(val, &origin, &call, &info, 0) - .map_err(extension_error)?; match with_evm_context(|| call.dispatch(origin)) { Ok(mut post_info) => { post_info.set_extension_weight(&info); - let result: DispatchResult = Ok(()); - as TransactionExtension< - ::RuntimeCall, - >>::post_dispatch((), &info, &mut post_info, 0, &result) - .map_err(extension_error)?; log::debug!("Dispatch succeeded. Post info: {post_info:?}"); self.charge_and_refund_after_dispatch::(&info, &post_info)?; @@ -149,11 +107,6 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { let err_str: &'static str = e.into(); let mut post_info = e.post_info; post_info.set_extension_weight(&info); - let result: DispatchResult = Err(e.error); - as TransactionExtension< - ::RuntimeCall, - >>::post_dispatch((), &info, &mut post_info, 0, &result) - .map_err(extension_error)?; log::info!("Precompile dispatch failed. message as: {e:?}"); self.charge_and_refund_after_dispatch::(&info, &post_info)?; @@ -197,12 +150,6 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { } } -fn extension_error(err: TransactionValidityError) -> PrecompileFailure { - PrecompileFailure::Error { - exit_status: ExitError::Other(format!("transaction extension rejected: {err:?}").into()), - } -} - impl PrecompileHandleExt for T where T: PrecompileHandle {} pub trait PrecompileExt>: Precompile { diff --git a/precompiles/src/mock.rs b/precompiles/src/mock.rs index cb7275e47c..976760d55a 100644 --- a/precompiles/src/mock.rs +++ b/precompiles/src/mock.rs @@ -178,6 +178,14 @@ impl frame_system::Config for Runtime { type MaxConsumers = ConstU32<16>; type Block = Block; type Nonce = u64; + type DispatchExtension = ( + pallet_subtensor::CheckColdkeySwap, + pallet_subtensor::CheckWeights, + pallet_subtensor::CheckRateLimits, + pallet_subtensor::CheckDelegateTake, + pallet_subtensor::CheckServingEndpoints, + pallet_subtensor::CheckEvmKeyAssociation, + ); } #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] diff --git a/precompiles/src/neuron.rs b/precompiles/src/neuron.rs index b0dd1ea720..8856acdbbd 100644 --- a/precompiles/src/neuron.rs +++ b/precompiles/src/neuron.rs @@ -260,8 +260,8 @@ mod tests { use super::*; use crate::PrecompileExt; use crate::mock::{ - AccountId, Runtime, addr_from_index, execute_precompile, mapped_account, new_test_ext, - precompiles, selector_u32, + AccountId, Runtime, System, addr_from_index, execute_precompile, mapped_account, + new_test_ext, precompiles, selector_u32, }; use precompile_utils::solidity::encode_with_selector; use precompile_utils::testing::PrecompileTesterExt; @@ -615,6 +615,48 @@ mod tests { }); } + #[test] + fn neuron_precompile_dispatch_runs_subtensor_dispatch_extensions() { + new_test_ext().execute_with(|| { + let caller = addr_from_index(0x5A34); + let (netuid, caller_account) = setup_registered_caller(caller); + let new_coldkey_hash = + ::Hashing::hash_of(&AccountId::new([0x99; 32])); + + pallet_subtensor::ColdkeySwapAnnouncements::::insert( + &caller_account, + (System::block_number(), new_coldkey_hash), + ); + + let rejected = execute_precompile( + &precompiles::>(), + addr_from_index(NeuronPrecompile::::INDEX), + caller, + encode_with_selector( + selector_u32("serveAxon(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8)"), + ( + TEST_NETUID_U16, + SERVE_VERSION, + SERVE_IP, + SERVE_PORT, + SERVE_IP_TYPE, + SERVE_PROTOCOL, + SERVE_PLACEHOLDER1, + SERVE_PLACEHOLDER2, + ), + ), + U256::zero(), + ) + .expect("serve axon should route to neuron precompile"); + + assert!(rejected.is_err()); + assert!( + pallet_subtensor::Axons::::get(netuid, caller_account).is_none(), + "dispatch extension rejection must happen before the call writes endpoint metadata" + ); + }); + } + #[test] fn neuron_precompile_serve_axon_tls_sets_axon_info_and_certificate() { new_test_ext().execute_with(|| { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index f18065f75c..51aa3420d8 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -347,7 +347,14 @@ impl frame_system::Config for Runtime { type PostInherents = (); type PostTransactions = (); type ExtensionsWeightInfo = frame_system::SubstrateExtensionsWeight; - type DispatchExtension = pallet_subtensor::CheckColdkeySwap; + type DispatchExtension = ( + pallet_subtensor::CheckColdkeySwap, + pallet_subtensor::CheckWeights, + pallet_subtensor::CheckRateLimits, + pallet_subtensor::CheckDelegateTake, + pallet_subtensor::CheckServingEndpoints, + pallet_subtensor::CheckEvmKeyAssociation, + ); } impl pallet_insecure_randomness_collective_flip::Config for Runtime {} diff --git a/runtime/src/migrations/pallet_registry_cleanup_migration.rs b/runtime/src/migrations/pallet_registry_cleanup_migration.rs index 9a98ce77c4..f12cdbdc36 100644 --- a/runtime/src/migrations/pallet_registry_cleanup_migration.rs +++ b/runtime/src/migrations/pallet_registry_cleanup_migration.rs @@ -15,6 +15,8 @@ use frame_support::{ }; use sp_io::hashing::twox_128; use sp_runtime::Saturating; +#[cfg(feature = "try-runtime")] +use subtensor_macros::freeze_struct; type DbWeightOf = ::DbWeight; #[cfg(feature = "try-runtime")] @@ -248,6 +250,7 @@ fn map_reason(reason: OldRuntimeHoldReason) -> Option { #[cfg(feature = "try-runtime")] #[derive(Encode, Decode)] +#[freeze_struct("d1c269899b95593c")] struct PreUpgradeState { total_issuance: BalanceOf, affected_accounts: Vec, @@ -255,6 +258,7 @@ struct PreUpgradeState { #[cfg(feature = "try-runtime")] #[derive(Encode, Decode)] +#[freeze_struct("dd446b32ea403051")] struct AffectedAccount { account_id: AccountIdOf, free: BalanceOf,