From 33f0144e823255ff2a8fe8ec75acc43690fe7d41 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Thu, 22 May 2025 17:15:05 +0400 Subject: [PATCH 01/10] Migrate serving rate limits --- pallets/admin-utils/src/lib.rs | 6 ++- pallets/subtensor/src/benchmarks.rs | 4 +- pallets/subtensor/src/lib.rs | 5 ++ pallets/subtensor/src/macros/hooks.rs | 4 +- .../migrate_obsolete_rate_limiting_maps.rs | 53 +++++++++++++++++++ pallets/subtensor/src/migrations/mod.rs | 1 + pallets/subtensor/src/tests/serving.rs | 4 +- pallets/subtensor/src/utils/misc.rs | 13 +++-- precompiles/src/subnet.rs | 2 +- 9 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 2b41539816..d690a06fec 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -196,7 +196,11 @@ pub mod pallet { ) -> DispatchResult { pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; - pallet_subtensor::Pallet::::set_serving_rate_limit(netuid, serving_rate_limit); + pallet_subtensor::Pallet::::set_serving_rate_limit( + netuid, + serving_rate_limit, + false, + ); log::debug!( "ServingRateLimitSet( serving_rate_limit: {:?} ) ", serving_rate_limit diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index a7cd03e652..6ec90940b9 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -349,7 +349,7 @@ mod pallet_benchmarks { netuid, caller.clone() )); - Subtensor::::set_serving_rate_limit(netuid, 0); + Subtensor::::set_serving_rate_limit(netuid, 0, false); #[extrinsic_call] _( @@ -387,7 +387,7 @@ mod pallet_benchmarks { netuid, caller.clone() )); - Subtensor::::set_serving_rate_limit(netuid, 0); + Subtensor::::set_serving_rate_limit(netuid, 0, false); #[extrinsic_call] _( diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 197cd5f8f7..fafda1130e 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -57,6 +57,7 @@ extern crate alloc; pub const MAX_CRV3_COMMIT_SIZE_BYTES: u32 = 5000; +#[allow(deprecated)] #[deny(missing_docs)] #[import_section(errors::errors)] #[import_section(events::events)] @@ -1323,6 +1324,8 @@ pub mod pallet { /// --- MAP ( netuid ) --> subnet_owner_hotkey pub type SubnetOwnerHotkey = StorageMap<_, Identity, u16, T::AccountId, ValueQuery, DefaultSubnetOwner>; + + #[deprecated] #[pallet::storage] /// --- MAP ( netuid ) --> serving_rate_limit pub type ServingRateLimit = @@ -2699,4 +2702,6 @@ impl CollectiveInterface for () { pub enum RateLimitKey { // The setting sn owner hotkey operation is rate limited per netuid SetSNOwnerHotkey(u16), + // An axon or prometheus serving rate limit for a registered neuron. + ServingRateLimit(u16), } diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index a0e2fc6e72..950f29fe11 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -115,7 +115,9 @@ mod hooks { // Reset max burn .saturating_add(migrations::migrate_reset_max_burn::migrate_reset_max_burn::()) // Migrate ColdkeySwapScheduled structure to new format - .saturating_add(migrations::migrate_coldkey_swap_scheduled::migrate_coldkey_swap_scheduled::()); + .saturating_add(migrations::migrate_coldkey_swap_scheduled::migrate_coldkey_swap_scheduled::()) + // Migrate rate limit maps to new format + .saturating_add(migrations::migrate_obsolete_rate_limiting_maps::migrate_obsolete_rate_limiting_maps::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs new file mode 100644 index 0000000000..f17eec84dc --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -0,0 +1,53 @@ +use crate::Vec; +use crate::{Config, HasMigrationRun, NetworksAdded, Pallet}; +use alloc::string::String; +use frame_support::IterableStorageMap; +use frame_support::traits::Get; +use frame_support::weights::Weight; + +#[allow(deprecated)] +pub fn migrate_obsolete_rate_limiting_maps() -> Weight { + let migration_name = b"migrate_obsolete_rate_limiting_maps".to_vec(); + + // Initialize the weight with one read operation. + let mut weight = T::DbWeight::get().reads(1); + + // Check if the migration has already run + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + migration_name + ); + return weight; + } + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + let netuids: Vec = as IterableStorageMap>::iter() + .map(|(netuid, _)| netuid) + .collect(); + weight = weight.saturating_add(T::DbWeight::get().reads(netuids.len() as u64)); + + for netuid in netuids.into_iter() { + let rate_limit = crate::ServingRateLimit::::get(netuid); + Pallet::::set_serving_rate_limit(netuid, rate_limit, true); + crate::ServingRateLimit::::remove(netuid); + + weight = weight.saturating_add(T::DbWeight::get().writes(2)); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + } + + // Mark the migration as completed + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed.", + String::from_utf8_lossy(&migration_name) + ); + + // Return the migration weight. + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index 5c6347034f..9a1e2a5eff 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -12,6 +12,7 @@ pub mod migrate_delete_subnet_3; pub mod migrate_fix_is_network_member; pub mod migrate_identities_v2; pub mod migrate_init_total_issuance; +pub mod migrate_obsolete_rate_limiting_maps; pub mod migrate_orphaned_storage_items; pub mod migrate_populate_owned_hotkeys; pub mod migrate_rao; diff --git a/pallets/subtensor/src/tests/serving.rs b/pallets/subtensor/src/tests/serving.rs index 251dde2078..26a1425695 100644 --- a/pallets/subtensor/src/tests/serving.rs +++ b/pallets/subtensor/src/tests/serving.rs @@ -283,7 +283,7 @@ fn test_axon_serving_rate_limit_exceeded() { placeholder1, placeholder2 )); - SubtensorModule::set_serving_rate_limit(netuid, 2); + SubtensorModule::set_serving_rate_limit(netuid, 2, false); run_to_block(2); // Go to block 2 // Needs to be 2 blocks apart, we are only 1 block apart assert_eq!( @@ -485,7 +485,7 @@ fn test_prometheus_serving_rate_limit_exceeded() { port, ip_type )); - SubtensorModule::set_serving_rate_limit(netuid, 1); + SubtensorModule::set_serving_rate_limit(netuid, 1, false); // Same block, need 1 block to pass assert_eq!( SubtensorModule::serve_prometheus( diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 899fa83646..5792f2c375 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -353,11 +353,16 @@ impl Pallet { } pub fn get_serving_rate_limit(netuid: u16) -> u64 { - ServingRateLimit::::get(netuid) + let limit_key = RateLimitKey::ServingRateLimit(netuid); + Self::get_rate_limited_last_block(&limit_key) } - pub fn set_serving_rate_limit(netuid: u16, serving_rate_limit: u64) { - ServingRateLimit::::insert(netuid, serving_rate_limit); - Self::deposit_event(Event::ServingRateLimitSet(netuid, serving_rate_limit)); + pub fn set_serving_rate_limit(netuid: u16, serving_rate_limit: u64, skip_event: bool) { + let limit_key = RateLimitKey::ServingRateLimit(netuid); + Self::set_rate_limited_last_block(&limit_key, serving_rate_limit); + + if !skip_event { + Self::deposit_event(Event::ServingRateLimitSet(netuid, serving_rate_limit)); + } } pub fn get_min_difficulty(netuid: u16) -> u64 { diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index 7d4dd175e3..6d6cab3e86 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -98,7 +98,7 @@ where #[precompile::public("getServingRateLimit(uint16)")] #[precompile::view] fn get_serving_rate_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::ServingRateLimit::::get(netuid)) + Ok(pallet_subtensor::pallet::Pallet::::get_serving_rate_limit(netuid)) } #[precompile::public("setServingRateLimit(uint16,uint64)")] From 76787b075d192d0c49bfe6e4521b3e6a5e24b111 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Mon, 26 May 2025 12:02:07 +0400 Subject: [PATCH 02/10] Refactor serving rate limits and add a test. --- .../migrate_obsolete_rate_limiting_maps.rs | 24 ++++++- pallets/subtensor/src/tests/migration.rs | 64 +++++++++++++++++++ 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs index f17eec84dc..c2316ee4d6 100644 --- a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -1,9 +1,12 @@ use crate::Vec; use crate::{Config, HasMigrationRun, NetworksAdded, Pallet}; use alloc::string::String; +use codec::{Decode, Encode}; use frame_support::IterableStorageMap; use frame_support::traits::Get; use frame_support::weights::Weight; +use sp_io::hashing::twox_128; +use sp_io::storage::{clear, get}; #[allow(deprecated)] pub fn migrate_obsolete_rate_limiting_maps() -> Weight { @@ -30,10 +33,25 @@ pub fn migrate_obsolete_rate_limiting_maps() -> Weight { .collect(); weight = weight.saturating_add(T::DbWeight::get().reads(netuids.len() as u64)); + let pallet_name = "SubtensorModule"; + let storage_name = "ServingRateLimit"; + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let prefix = [pallet_name_hash, storage_name_hash].concat(); + for netuid in netuids.into_iter() { - let rate_limit = crate::ServingRateLimit::::get(netuid); - Pallet::::set_serving_rate_limit(netuid, rate_limit, true); - crate::ServingRateLimit::::remove(netuid); + let mut encoded_netuid = netuid.encode(); + let mut full_key = prefix.clone(); + + full_key.append(&mut encoded_netuid); + + if let Some(value_bytes) = get(&full_key) { + if let Ok(rate_limit) = Decode::decode(&mut &value_bytes[..]) { + Pallet::::set_serving_rate_limit(netuid, rate_limit, true); + } + + clear(&full_key); + } weight = weight.saturating_add(T::DbWeight::get().writes(2)); weight = weight.saturating_add(T::DbWeight::get().reads(1)); diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 1dfac06ad5..7c43aa694e 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -820,3 +820,67 @@ fn test_migrate_remove_commitments_rate_limit() { assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); } + +#[test] +fn test_migrate_serving_rate_limit() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_obsolete_rate_limiting_maps"; + + let pallet_name = "SubtensorModule"; + let storage_name = "ServingRateLimit"; + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let prefix = [pallet_name_hash, storage_name_hash].concat(); + + let netuid = 1u16; + add_network(netuid, 1, 0); + let mut encoded_netuid = netuid.encode(); + let mut full_key = prefix.clone(); + + full_key.append(&mut encoded_netuid); + + let original_value: u64 = 123; + put_raw(&full_key, &original_value.encode()); + + let stored_before = get_raw(&full_key).expect("Expected RateLimit to exist"); + assert_eq!( + u64::decode(&mut &stored_before[..]).expect("Failed to decode RateLimit"), + original_value + ); + + assert!( + !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should not have run yet" + ); + + // ------------------------------ + // Step 2: Run the Migration + // ------------------------------ + let weight = crate::migrations::migrate_obsolete_rate_limiting_maps:: + migrate_obsolete_rate_limiting_maps::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!( + SubtensorModule::get_serving_rate_limit(netuid), + original_value + ); + assert_eq!( + get_raw(&full_key), + None, + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} From cdabcc6d68b30cffce3d2164349ecee2fb7f4507 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Wed, 28 May 2025 16:31:59 +0400 Subject: [PATCH 03/10] Migrate TxRateLimit --- pallets/subtensor/src/lib.rs | 2 ++ pallets/subtensor/src/utils/misc.rs | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index fafda1130e..62089fcf28 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2704,4 +2704,6 @@ pub enum RateLimitKey { SetSNOwnerHotkey(u16), // An axon or prometheus serving rate limit for a registered neuron. ServingRateLimit(u16), + // Limits transaction number + TxRateLimit, } diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 5792f2c375..4b7b6b04cd 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -293,10 +293,11 @@ impl Pallet { // Configure tx rate limiting pub fn get_tx_rate_limit() -> u64 { - TxRateLimit::::get() + LastRateLimitedBlock::::get(RateLimitKey::TxRateLimit) } pub fn set_tx_rate_limit(tx_rate_limit: u64) { - TxRateLimit::::put(tx_rate_limit); + LastRateLimitedBlock::::set(RateLimitKey::TxRateLimit, tx_rate_limit); + Self::deposit_event(Event::TxRateLimitSet(tx_rate_limit)); } pub fn get_tx_delegate_take_rate_limit() -> u64 { From 30c6d4d6e28586e1cb9b31bddac322f53a416914 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Fri, 23 May 2025 19:37:17 +0400 Subject: [PATCH 04/10] Change migration type for rate limits --- .../src/migrations/migrate_obsolete_rate_limiting_maps.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs index c2316ee4d6..b381970638 100644 --- a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -52,7 +52,7 @@ pub fn migrate_obsolete_rate_limiting_maps() -> Weight { clear(&full_key); } - + weight = weight.saturating_add(T::DbWeight::get().writes(2)); weight = weight.saturating_add(T::DbWeight::get().reads(1)); } From cd68f34d1bcf0b4246fd93617178a089e96c91c3 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Fri, 30 May 2025 13:04:48 +0400 Subject: [PATCH 05/10] Refactor TxRateLimits migration and add test --- pallets/admin-utils/src/lib.rs | 2 +- .../migrate_obsolete_rate_limiting_maps.rs | 106 ++++++++++++++++-- pallets/subtensor/src/tests/migration.rs | 58 +++++++++- pallets/subtensor/src/tests/swap_hotkey.rs | 2 +- pallets/subtensor/src/utils/misc.rs | 6 +- 5 files changed, 161 insertions(+), 13 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index d690a06fec..39dfbe49b7 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -177,7 +177,7 @@ pub mod pallet { #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn sudo_set_tx_rate_limit(origin: OriginFor, tx_rate_limit: u64) -> DispatchResult { ensure_root(origin)?; - pallet_subtensor::Pallet::::set_tx_rate_limit(tx_rate_limit); + pallet_subtensor::Pallet::::set_tx_rate_limit(tx_rate_limit, false); log::debug!("TxRateLimitSet( tx_rate_limit: {:?} ) ", tx_rate_limit); Ok(()) } diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs index b381970638..a9a6c50e4d 100644 --- a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -8,10 +8,48 @@ use frame_support::weights::Weight; use sp_io::hashing::twox_128; use sp_io::storage::{clear, get}; -#[allow(deprecated)] pub fn migrate_obsolete_rate_limiting_maps() -> Weight { - let migration_name = b"migrate_obsolete_rate_limiting_maps".to_vec(); + migrate_serving_rate_limits::().saturating_add(migrate_tx_rate_limits::()) +} + +pub fn migrate_tx_rate_limits() -> Weight { + let migration_name = b"migrate_tx_rate_limits".to_vec(); + let pallet_name = "SubtensorModule"; + let storage_name = "TxRateLimit"; + migrate_value::(migration_name, pallet_name, storage_name, |limit| { + Pallet::::set_tx_rate_limit(limit, true); + }) +} + +pub fn migrate_serving_rate_limits() -> Weight { + let migration_name = b"migrate_serving_rate_limits".to_vec(); + let pallet_name = "SubtensorModule"; + let storage_name = "ServingRateLimit"; + + migrate_limit_map_netuids::( + migration_name, + pallet_name, + storage_name, + |netuid| netuid.encode(), + |netuid, limit| { + Pallet::::set_serving_rate_limit(netuid, limit, true); + }, + ) +} + +fn migrate_limit_map_netuids( + migration_name: Vec, + pallet_name: &str, + storage_name: &str, + key: KeyFunction, + set_value: SetValueFunction, +) -> Weight +where + T: Config, + KeyFunction: Fn(u16 /*netuid*/) -> Vec, + SetValueFunction: Fn(u16 /*netuid*/, u64 /*limit in blocks*/), +{ // Initialize the weight with one read operation. let mut weight = T::DbWeight::get().reads(1); @@ -33,26 +71,24 @@ pub fn migrate_obsolete_rate_limiting_maps() -> Weight { .collect(); weight = weight.saturating_add(T::DbWeight::get().reads(netuids.len() as u64)); - let pallet_name = "SubtensorModule"; - let storage_name = "ServingRateLimit"; let pallet_name_hash = twox_128(pallet_name.as_bytes()); let storage_name_hash = twox_128(storage_name.as_bytes()); let prefix = [pallet_name_hash, storage_name_hash].concat(); for netuid in netuids.into_iter() { - let mut encoded_netuid = netuid.encode(); let mut full_key = prefix.clone(); + let mut key = key(netuid); - full_key.append(&mut encoded_netuid); + full_key.append(&mut key); if let Some(value_bytes) = get(&full_key) { if let Ok(rate_limit) = Decode::decode(&mut &value_bytes[..]) { - Pallet::::set_serving_rate_limit(netuid, rate_limit, true); + set_value(netuid, rate_limit); } clear(&full_key); } - + weight = weight.saturating_add(T::DbWeight::get().writes(2)); weight = weight.saturating_add(T::DbWeight::get().reads(1)); } @@ -69,3 +105,57 @@ pub fn migrate_obsolete_rate_limiting_maps() -> Weight { // Return the migration weight. weight } + +fn migrate_value( + migration_name: Vec, + pallet_name: &str, + storage_name: &str, + set_value: SetValueFunction, +) -> Weight +where + T: Config, + SetValueFunction: Fn(u64 /*limit in blocks*/), +{ + // Initialize the weight with one read operation. + let mut weight = T::DbWeight::get().reads(1); + + // Check if the migration has already run + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + migration_name + ); + return weight; + } + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let full_key = [pallet_name_hash, storage_name_hash].concat(); + + if let Some(value_bytes) = get(&full_key) { + if let Ok(rate_limit) = Decode::decode(&mut &value_bytes[..]) { + set_value(rate_limit); + } + + clear(&full_key); + } + + weight = weight.saturating_add(T::DbWeight::get().writes(2)); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + + // Mark the migration as completed + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed.", + String::from_utf8_lossy(&migration_name) + ); + + // Return the migration weight. + weight +} diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 7c43aa694e..5c30e347c9 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -827,7 +827,7 @@ fn test_migrate_serving_rate_limit() { // ------------------------------ // Step 1: Simulate Old Storage Entry // ------------------------------ - const MIGRATION_NAME: &str = "migrate_obsolete_rate_limiting_maps"; + const MIGRATION_NAME: &str = "migrate_serving_rate_limits"; let pallet_name = "SubtensorModule"; let storage_name = "ServingRateLimit"; @@ -884,3 +884,59 @@ fn test_migrate_serving_rate_limit() { assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); } + +#[test] +fn test_migrate_tx_rate_limit() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_tx_rate_limits"; + + let pallet_name = "SubtensorModule"; + let storage_name = "TxRateLimit"; + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let prefix = [pallet_name_hash, storage_name_hash].concat(); + + let mut full_key = prefix.clone(); + + let original_value: u64 = 123; + put_raw(&full_key, &original_value.encode()); + + let stored_before = get_raw(&full_key).expect("Expected RateLimit to exist"); + assert_eq!( + u64::decode(&mut &stored_before[..]).expect("Failed to decode RateLimit"), + original_value + ); + + assert!( + !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should not have run yet" + ); + + // ------------------------------ + // Step 2: Run the Migration + // ------------------------------ + let weight = crate::migrations::migrate_obsolete_rate_limiting_maps:: + migrate_obsolete_rate_limiting_maps::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!(SubtensorModule::get_tx_rate_limit(), original_value); + assert_eq!( + get_raw(&full_key), + None, + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} diff --git a/pallets/subtensor/src/tests/swap_hotkey.rs b/pallets/subtensor/src/tests/swap_hotkey.rs index a82972c2f7..a6d2b1b625 100644 --- a/pallets/subtensor/src/tests/swap_hotkey.rs +++ b/pallets/subtensor/src/tests/swap_hotkey.rs @@ -729,7 +729,7 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { log::info!("current_tx_rate_limit: {:?}", current_tx_rate_limit); // Set the transaction rate limit - SubtensorModule::set_tx_rate_limit(tx_rate_limit); + SubtensorModule::set_tx_rate_limit(tx_rate_limit, false); // assert the rate limit is set to 1000 blocks assert_eq!(SubtensorModule::get_tx_rate_limit(), tx_rate_limit); diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 4b7b6b04cd..39913e4d76 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -295,10 +295,12 @@ impl Pallet { pub fn get_tx_rate_limit() -> u64 { LastRateLimitedBlock::::get(RateLimitKey::TxRateLimit) } - pub fn set_tx_rate_limit(tx_rate_limit: u64) { + pub fn set_tx_rate_limit(tx_rate_limit: u64, skip_event: bool) { LastRateLimitedBlock::::set(RateLimitKey::TxRateLimit, tx_rate_limit); - Self::deposit_event(Event::TxRateLimitSet(tx_rate_limit)); + if !skip_event { + Self::deposit_event(Event::TxRateLimitSet(tx_rate_limit)); + } } pub fn get_tx_delegate_take_rate_limit() -> u64 { TxDelegateTakeRateLimit::::get() From 7ebb4562d395641e1a654f3fb9280912f11cec4f Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Fri, 30 May 2025 13:19:33 +0400 Subject: [PATCH 06/10] Migrate set_weights rate limit. --- pallets/admin-utils/src/lib.rs | 1 + pallets/subtensor/src/benchmarks.rs | 2 +- pallets/subtensor/src/lib.rs | 2 + .../migrate_obsolete_rate_limiting_maps.rs | 20 ++++- pallets/subtensor/src/tests/children.rs | 8 +- pallets/subtensor/src/tests/coinbase.rs | 6 +- pallets/subtensor/src/tests/epoch.rs | 10 +-- pallets/subtensor/src/tests/migration.rs | 64 +++++++++++++++ pallets/subtensor/src/tests/staking.rs | 2 +- pallets/subtensor/src/tests/weights.rs | 82 +++++++++---------- pallets/subtensor/src/utils/misc.rs | 19 +++-- 11 files changed, 153 insertions(+), 63 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 39dfbe49b7..58a4257b1f 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -333,6 +333,7 @@ pub mod pallet { pallet_subtensor::Pallet::::set_weights_set_rate_limit( netuid, weights_set_rate_limit, + false, ); log::debug!( "WeightsSetRateLimitSet( netuid: {:?} weights_set_rate_limit: {:?} ) ", diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 6ec90940b9..54c13bb6ca 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -670,7 +670,7 @@ mod pallet_benchmarks { Subtensor::::set_network_registration_allowed(netuid, true); Subtensor::::set_network_pow_registration_allowed(netuid, true); Subtensor::::set_commit_reveal_weights_enabled(netuid, true); - Subtensor::::set_weights_set_rate_limit(netuid, 0); + Subtensor::::set_weights_set_rate_limit(netuid, 0, false); let block_number: u64 = Subtensor::::get_current_block_as_u64(); let (nonce, work) = diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 62089fcf28..7b18d3c9e7 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2706,4 +2706,6 @@ pub enum RateLimitKey { ServingRateLimit(u16), // Limits transaction number TxRateLimit, + // Limits set_weights operation + SetWeightsRateLimit(u16), } diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs index a9a6c50e4d..b66505311e 100644 --- a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -9,7 +9,9 @@ use sp_io::hashing::twox_128; use sp_io::storage::{clear, get}; pub fn migrate_obsolete_rate_limiting_maps() -> Weight { - migrate_serving_rate_limits::().saturating_add(migrate_tx_rate_limits::()) + migrate_serving_rate_limits::() + .saturating_add(migrate_tx_rate_limits::()) + .saturating_add(migrate_set_weights_rate_limits::()) } pub fn migrate_tx_rate_limits() -> Weight { @@ -38,6 +40,22 @@ pub fn migrate_serving_rate_limits() -> Weight { ) } +pub fn migrate_set_weights_rate_limits() -> Weight { + let migration_name = b"migrate_set_weights_rate_limits".to_vec(); + let pallet_name = "SubtensorModule"; + let storage_name = "WeightsSetRateLimit"; + + migrate_limit_map_netuids::( + migration_name, + pallet_name, + storage_name, + |netuid| netuid.encode(), + |netuid, limit| { + Pallet::::set_weights_set_rate_limit(netuid, limit, true); + }, + ) +} + fn migrate_limit_map_netuids( migration_name: Vec, pallet_name: &str, diff --git a/pallets/subtensor/src/tests/children.rs b/pallets/subtensor/src/tests/children.rs index 1a9016f13f..ef6add3bf7 100644 --- a/pallets/subtensor/src/tests/children.rs +++ b/pallets/subtensor/src/tests/children.rs @@ -2625,7 +2625,7 @@ fn test_childkey_set_weights_single_parent() { 1_000_000, ); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); // Set parent-child relationship mock_set_children_no_epochs(netuid, &parent, &[(u64::MAX, child)]); @@ -2720,7 +2720,7 @@ fn test_set_weights_no_parent() { stake_to_give_child, ); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); // Has stake and no parent step_block(7200 + 1); @@ -2824,7 +2824,7 @@ fn test_childkey_take_drain() { &nominator, stake + ExistentialDeposit::get(), ); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_max_allowed_validators(netuid, 2); step_block(subnet_tempo); SubnetOwnerCut::::set(0); @@ -3575,7 +3575,7 @@ fn test_dynamic_parent_child_relationships() { let version_key = SubtensorModule::get_weights_version_key(netuid); // Ensure we can set weights without rate limiting - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); assert_ok!(SubtensorModule::set_weights( origin, diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 1345f36b7d..d3199f4350 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -1902,7 +1902,7 @@ fn test_drain_pending_emission_zero_emission() { let tempo = 2; SubtensorModule::set_tempo(netuid, tempo); // Set weight-set limit to 0. - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, hotkey, coldkey, 0); register_ok_neuron(netuid, miner_hk, miner_ck, 0); @@ -1975,7 +1975,7 @@ fn test_run_coinbase_not_started() { let tempo = 2; SubtensorModule::set_tempo(netuid, tempo); // Set weight-set limit to 0. - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, hotkey, coldkey, 0); register_ok_neuron(netuid, miner_hk, miner_ck, 0); @@ -2057,7 +2057,7 @@ fn test_run_coinbase_not_started_start_after() { let tempo = 2; SubtensorModule::set_tempo(netuid, tempo); // Set weight-set limit to 0. - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, hotkey, coldkey, 0); register_ok_neuron(netuid, miner_hk, miner_ck, 0); diff --git a/pallets/subtensor/src/tests/epoch.rs b/pallets/subtensor/src/tests/epoch.rs index 2557709912..28f4da6535 100644 --- a/pallets/subtensor/src/tests/epoch.rs +++ b/pallets/subtensor/src/tests/epoch.rs @@ -999,7 +999,7 @@ fn test_bonds() { assert_eq!(SubtensorModule::get_max_allowed_uids(netuid), n); SubtensorModule::set_max_registrations_per_block( netuid, n ); SubtensorModule::set_target_registrations_per_interval(netuid, n); - SubtensorModule::set_weights_set_rate_limit( netuid, 0 ); + SubtensorModule::set_weights_set_rate_limit( netuid, 0, false ); SubtensorModule::set_min_allowed_weights( netuid, 1 ); SubtensorModule::set_max_weight_limit( netuid, u16::MAX ); SubtensorModule::set_bonds_penalty(netuid, u16::MAX); @@ -1546,7 +1546,7 @@ fn test_outdated_weights() { let stake: u64 = 1; add_network(netuid, tempo, 0); SubtensorModule::set_max_allowed_uids(netuid, n); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_max_registrations_per_block(netuid, n); SubtensorModule::set_target_registrations_per_interval(netuid, n); SubtensorModule::set_min_allowed_weights(netuid, 0); @@ -1733,7 +1733,7 @@ fn test_zero_weights() { let stake: u64 = 1; add_network(netuid, tempo, 0); SubtensorModule::set_max_allowed_uids(netuid, n); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_max_registrations_per_block(netuid, n); SubtensorModule::set_target_registrations_per_interval(netuid, n); SubtensorModule::set_min_allowed_weights(netuid, 0); @@ -1927,7 +1927,7 @@ fn test_deregistered_miner_bonds() { let stake: u64 = 1; add_network(netuid, high_tempo, 0); SubtensorModule::set_max_allowed_uids(netuid, n); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_max_registrations_per_block(netuid, n); SubtensorModule::set_target_registrations_per_interval(netuid, n); SubtensorModule::set_min_allowed_weights(netuid, 0); @@ -2639,7 +2639,7 @@ fn setup_yuma_3_scenario(netuid: u16, n: u16, sparse: bool, max_stake: u64, stak assert_eq!(SubtensorModule::get_max_allowed_uids(netuid), n); SubtensorModule::set_max_registrations_per_block(netuid, n); SubtensorModule::set_target_registrations_per_interval(netuid, n); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_min_allowed_weights(netuid, 1); SubtensorModule::set_max_weight_limit(netuid, u16::MAX); SubtensorModule::set_bonds_penalty(netuid, 0); diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 5c30e347c9..040d2d8bba 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -940,3 +940,67 @@ fn test_migrate_tx_rate_limit() { assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); } + +#[test] +fn test_migrate_set_weights_rate_limit() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_set_weights_rate_limits"; + + let pallet_name = "SubtensorModule"; + let storage_name = "WeightsSetRateLimit"; + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let prefix = [pallet_name_hash, storage_name_hash].concat(); + + let netuid = 1u16; + add_network(netuid, 1, 0); + let mut encoded_netuid = netuid.encode(); + let mut full_key = prefix.clone(); + + full_key.append(&mut encoded_netuid); + + let original_value: u64 = 123; + put_raw(&full_key, &original_value.encode()); + + let stored_before = get_raw(&full_key).expect("Expected RateLimit to exist"); + assert_eq!( + u64::decode(&mut &stored_before[..]).expect("Failed to decode RateLimit"), + original_value + ); + + assert!( + !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should not have run yet" + ); + + // ------------------------------ + // Step 2: Run the Migration + // ------------------------------ + let weight = crate::migrations::migrate_obsolete_rate_limiting_maps:: + migrate_obsolete_rate_limiting_maps::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!( + SubtensorModule::get_weights_set_rate_limit(netuid), + original_value + ); + assert_eq!( + get_raw(&full_key), + None, + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 9a672676ee..4cb6cf25e5 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -3257,7 +3257,7 @@ fn test_mining_emission_distribution_validator_valiminer_miner() { &miner_coldkey, stake + ExistentialDeposit::get(), ); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); step_block(subnet_tempo); SubnetOwnerCut::::set(0); // There are two validators and three neurons diff --git a/pallets/subtensor/src/tests/weights.rs b/pallets/subtensor/src/tests/weights.rs index 3d240750cf..6d19936dfd 100644 --- a/pallets/subtensor/src/tests/weights.rs +++ b/pallets/subtensor/src/tests/weights.rs @@ -684,7 +684,7 @@ fn test_weights_err_setting_weights_too_fast() { netuid, 1, ); - SubtensorModule::set_weights_set_rate_limit(netuid, 10); + SubtensorModule::set_weights_set_rate_limit(netuid, 10, false); assert_eq!(SubtensorModule::get_weights_set_rate_limit(netuid), 10); let weights_keys: Vec = vec![1, 2]; @@ -1526,7 +1526,7 @@ fn test_reveal_weights_when_commit_reveal_disabled() { // Register neurons and set up configurations register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); @@ -1587,7 +1587,7 @@ fn test_commit_reveal_weights_ok() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -1655,7 +1655,7 @@ fn test_commit_reveal_tempo_interval() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -1791,7 +1791,7 @@ fn test_commit_reveal_hash() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); @@ -1891,7 +1891,7 @@ fn test_commit_reveal_disabled_or_enabled() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); @@ -1970,7 +1970,7 @@ fn test_toggle_commit_reveal_weights_and_set_weights() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -2053,7 +2053,7 @@ fn test_tempo_change_during_commit_reveal_process() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -2202,7 +2202,7 @@ fn test_commit_reveal_multiple_commits() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -2601,7 +2601,7 @@ fn test_expired_commits_handling_in_commit_and_reveal() { add_network(netuid, tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); // Register neurons register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); @@ -2800,7 +2800,7 @@ fn test_reveal_at_exact_epoch() { add_network(netuid, tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); @@ -2964,7 +2964,7 @@ fn test_tempo_and_reveal_period_change_during_commit_reveal_process() { SubtensorModule::set_reveal_period(netuid, initial_reveal_period); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); @@ -3154,7 +3154,7 @@ fn test_commit_reveal_order_enforcement() { add_network(netuid, tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); @@ -3256,7 +3256,7 @@ fn test_reveal_at_exact_block() { add_network(netuid, tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); @@ -3426,7 +3426,7 @@ fn test_successful_batch_reveal() { add_network(netuid, tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); @@ -3504,7 +3504,7 @@ fn test_batch_reveal_with_expired_commits() { add_network(netuid, tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); @@ -3756,7 +3756,7 @@ fn test_batch_reveal_before_reveal_period() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); @@ -3814,7 +3814,7 @@ fn test_batch_reveal_after_commits_expired() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); @@ -3921,7 +3921,7 @@ fn test_batch_reveal_with_out_of_order_commits() { add_network(netuid, tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); @@ -4032,7 +4032,7 @@ fn test_highly_concurrent_commits_and_reveals_with_multiple_hotkeys() { // ==== Setup Network ==== add_network(netuid, initial_tempo, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_reveal_period(netuid, initial_reveal_period); SubtensorModule::set_max_registrations_per_block(netuid, u16::MAX); SubtensorModule::set_target_registrations_per_interval(netuid, u16::MAX); @@ -4329,7 +4329,7 @@ fn test_get_reveal_blocks() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -4463,7 +4463,7 @@ fn test_commit_weights_rate_limit() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 10); // Rate limit is 10 blocks + SubtensorModule::set_weights_set_rate_limit(netuid, 10, false); // Rate limit is 10 blocks SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -4646,7 +4646,7 @@ fn test_reveal_crv3_commits_success() { register_ok_neuron(netuid, hotkey1, U256::from(3), 100_000); register_ok_neuron(netuid, hotkey2, U256::from(4), 100_000); SubtensorModule::set_stake_threshold(0); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 3); @@ -4801,7 +4801,7 @@ fn test_reveal_crv3_commits_cannot_reveal_after_reveal_epoch() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey1, U256::from(3), 100_000); register_ok_neuron(netuid, hotkey2, U256::from(4), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 3); @@ -4925,7 +4925,7 @@ fn test_do_commit_crv3_weights_success() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); assert_ok!(SubtensorModule::do_commit_crv3_weights( @@ -4959,7 +4959,7 @@ fn test_do_commit_crv3_weights_disabled() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_commit_reveal_weights_enabled(netuid, false); assert_err!( @@ -4988,7 +4988,7 @@ fn test_do_commit_crv3_weights_hotkey_not_registered() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); assert_err!( @@ -5017,7 +5017,7 @@ fn test_do_commit_crv3_weights_committing_too_fast() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::set_weights_set_rate_limit(netuid, 5, false); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); let neuron_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).expect("Expected uid"); @@ -5087,7 +5087,7 @@ fn test_do_commit_crv3_weights_too_many_unrevealed_commits() { register_ok_neuron(netuid, hotkey1, U256::from(2), 100_000); register_ok_neuron(netuid, hotkey2, U256::from(3), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); // Hotkey1 submits 10 commits successfully for i in 0..10 { @@ -5189,7 +5189,7 @@ fn test_reveal_crv3_commits_decryption_failure() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); let commit_bytes: Vec = vec![0xff; 100]; @@ -5246,7 +5246,7 @@ fn test_reveal_crv3_commits_multiple_commits_some_fail_some_succeed() { register_ok_neuron(netuid, hotkey2, U256::from(4), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 1); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); // Prepare a valid payload for hotkey1 let neuron_uid1 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey1) @@ -5368,7 +5368,7 @@ fn test_reveal_crv3_commits_do_set_weights_failure() { register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 3); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); // Prepare payload with mismatched uids and values lengths let version_key = SubtensorModule::get_weights_version_key(netuid); @@ -5454,7 +5454,7 @@ fn test_reveal_crv3_commits_payload_decoding_failure() { register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 3); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); let invalid_payload = vec![0u8; 10]; // Not a valid encoding of WeightsTlockPayload @@ -5533,7 +5533,7 @@ fn test_reveal_crv3_commits_signature_deserialization_failure() { register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 3); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); let version_key = SubtensorModule::get_weights_version_key(netuid); let payload = WeightsTlockPayload { @@ -5612,7 +5612,7 @@ fn test_do_commit_crv3_weights_commit_size_exceeds_limit() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); let max_commit_size = MAX_CRV3_COMMIT_SIZE_BYTES as usize; let commit_data_exceeding: Vec = vec![0u8; max_commit_size + 1]; // Exceeds max size @@ -5652,7 +5652,7 @@ fn test_reveal_crv3_commits_with_empty_commit_queue() { add_network(netuid, 5, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); step_epochs(2, netuid); @@ -5678,7 +5678,7 @@ fn test_reveal_crv3_commits_with_incorrect_identity_message() { register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 1); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); // Prepare a valid payload but use incorrect identity message during encryption let neuron_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey) @@ -5764,7 +5764,7 @@ fn test_multiple_commits_by_same_hotkey_within_limit() { register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 1); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); for i in 0..10 { let commit_data: Vec = vec![i; 5]; @@ -5802,7 +5802,7 @@ fn test_reveal_crv3_commits_removes_past_epoch_commits() { register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 1); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); let current_block = SubtensorModule::get_current_block_as_u64(); let current_epoch = SubtensorModule::get_epoch_index(netuid, current_block); @@ -5867,7 +5867,7 @@ fn test_reveal_crv3_commits_multiple_valid_commits_all_processed() { add_network(netuid, 5, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 1); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_max_registrations_per_block(netuid, 100); SubtensorModule::set_target_registrations_per_interval(netuid, 100); @@ -6055,7 +6055,7 @@ fn test_reveal_crv3_commits_max_neurons() { add_network(netuid, 5, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 1); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_weights_set_rate_limit(netuid, 0, false); SubtensorModule::set_max_registrations_per_block(netuid, 10000); SubtensorModule::set_target_registrations_per_interval(netuid, 10000); SubtensorModule::set_max_allowed_uids(netuid, 10024); diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 39913e4d76..499dd20209 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -393,14 +393,19 @@ impl Pallet { } pub fn get_weights_set_rate_limit(netuid: u16) -> u64 { - WeightsSetRateLimit::::get(netuid) + let limit_key = RateLimitKey::SetWeightsRateLimit(netuid); + LastRateLimitedBlock::::get(&limit_key) } - pub fn set_weights_set_rate_limit(netuid: u16, weights_set_rate_limit: u64) { - WeightsSetRateLimit::::insert(netuid, weights_set_rate_limit); - Self::deposit_event(Event::WeightsSetRateLimitSet( - netuid, - weights_set_rate_limit, - )); + pub fn set_weights_set_rate_limit(netuid: u16, weights_set_rate_limit: u64, skip_event: bool) { + let limit_key = RateLimitKey::SetWeightsRateLimit(netuid); + LastRateLimitedBlock::::insert(&limit_key, weights_set_rate_limit); + + if !skip_event { + Self::deposit_event(Event::WeightsSetRateLimitSet( + netuid, + weights_set_rate_limit, + )); + } } pub fn get_adjustment_interval(netuid: u16) -> u16 { From 5176ac76e19ec2ef496a28817d118965ca24008e Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Fri, 30 May 2025 13:49:07 +0400 Subject: [PATCH 07/10] Migrate NetworkRateLimit --- pallets/admin-utils/src/lib.rs | 2 +- pallets/subtensor/src/benchmarks.rs | 4 +- pallets/subtensor/src/lib.rs | 2 + .../migrate_obsolete_rate_limiting_maps.rs | 10 ++++ pallets/subtensor/src/subnets/subnet.rs | 15 +++-- pallets/subtensor/src/tests/migration.rs | 55 +++++++++++++++++++ pallets/subtensor/src/utils/rate_limiting.rs | 2 +- 7 files changed, 82 insertions(+), 8 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 58a4257b1f..5597dd234f 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -913,7 +913,7 @@ pub mod pallet { rate_limit: u64, ) -> DispatchResult { ensure_root(origin)?; - pallet_subtensor::Pallet::::set_network_rate_limit(rate_limit); + pallet_subtensor::Pallet::::set_network_rate_limit(rate_limit, false); log::debug!("NetworkRateLimit( rate_limit: {:?} ) ", rate_limit); Ok(()) } diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 54c13bb6ca..056e57c740 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -451,7 +451,7 @@ mod pallet_benchmarks { let coldkey: T::AccountId = account("Test", 0, seed); let hotkey: T::AccountId = account("TestHotkey", 0, seed); - Subtensor::::set_network_rate_limit(1); + Subtensor::::set_network_rate_limit(1, false); let amount: u64 = 100_000_000_000_000u64.saturating_mul(2); Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); @@ -1303,7 +1303,7 @@ mod pallet_benchmarks { let identity: Option = None; Subtensor::::set_network_registration_allowed(1, true); - Subtensor::::set_network_rate_limit(1); + Subtensor::::set_network_rate_limit(1, false); let amount: u64 = 9_999_999_999_999; Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 7b18d3c9e7..8e60fb8124 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2708,4 +2708,6 @@ pub enum RateLimitKey { TxRateLimit, // Limits set_weights operation SetWeightsRateLimit(u16), + // Network rate limits + NetworkRateLimit, } diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs index b66505311e..6513f4c1aa 100644 --- a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -12,8 +12,18 @@ pub fn migrate_obsolete_rate_limiting_maps() -> Weight { migrate_serving_rate_limits::() .saturating_add(migrate_tx_rate_limits::()) .saturating_add(migrate_set_weights_rate_limits::()) + .saturating_add(migrate_network_rate_limits::()) } +pub fn migrate_network_rate_limits() -> Weight { + let migration_name = b"migrate_network_rate_limits".to_vec(); + let pallet_name = "SubtensorModule"; + let storage_name = "NetworkRateLimit"; + + migrate_value::(migration_name, pallet_name, storage_name, |limit| { + Pallet::::set_network_rate_limit(limit, true); + }) +} pub fn migrate_tx_rate_limits() -> Weight { let migration_name = b"migrate_tx_rate_limits".to_vec(); let pallet_name = "SubtensorModule"; diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index b122bfa049..6f4e95774c 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -85,9 +85,16 @@ impl Pallet { /// Sets the network rate limit and emit the `NetworkRateLimitSet` event /// - pub fn set_network_rate_limit(limit: u64) { - NetworkRateLimit::::set(limit); - Self::deposit_event(Event::NetworkRateLimitSet(limit)); + pub fn set_network_rate_limit(limit: u64, skip_event: bool) { + LastRateLimitedBlock::::insert(RateLimitKey::NetworkRateLimit, limit); + + if !skip_event { + Self::deposit_event(Event::NetworkRateLimitSet(limit)); + } + } + /// Gets the network rate limit + pub fn get_network_rate_limit() -> u64 { + LastRateLimitedBlock::::get(RateLimitKey::NetworkRateLimit) } /// Checks if registrations are allowed for a given subnet. @@ -147,7 +154,7 @@ impl Pallet { let current_block = Self::get_current_block_as_u64(); let last_lock_block = Self::get_network_last_lock_block(); ensure!( - current_block.saturating_sub(last_lock_block) >= NetworkRateLimit::::get(), + current_block.saturating_sub(last_lock_block) >= Self::get_network_rate_limit(), Error::::NetworkTxRateLimitExceeded ); diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 040d2d8bba..0da980fb36 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -1004,3 +1004,58 @@ fn test_migrate_set_weights_rate_limit() { assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); } +#[test] +fn test_migrate_network_rate_limit() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_network_rate_limits"; + + let pallet_name = "SubtensorModule"; + let storage_name = "NetworkRateLimit"; + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let prefix = [pallet_name_hash, storage_name_hash].concat(); + + let mut full_key = prefix.clone(); + + let original_value: u64 = 123; + put_raw(&full_key, &original_value.encode()); + + let stored_before = get_raw(&full_key).expect("Expected RateLimit to exist"); + assert_eq!( + u64::decode(&mut &stored_before[..]).expect("Failed to decode RateLimit"), + original_value + ); + + assert!( + !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should not have run yet" + ); + + // ------------------------------ + // Step 2: Run the Migration + // ------------------------------ + let weight = crate::migrations::migrate_obsolete_rate_limiting_maps:: + migrate_obsolete_rate_limiting_maps::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!(SubtensorModule::get_network_rate_limit(), original_value); + assert_eq!( + get_raw(&full_key), + None, + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index 7edaebc98a..f1b103ba48 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -47,7 +47,7 @@ impl Pallet { match tx_type { TransactionType::SetChildren => 150, // 30 minutes TransactionType::SetChildkeyTake => TxChildkeyTakeRateLimit::::get(), - TransactionType::RegisterNetwork => NetworkRateLimit::::get(), + TransactionType::RegisterNetwork => Self::get_network_rate_limit(), TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) _ => 0, From 7e47d1265f845384adc8eb18f04e749701211175 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Fri, 30 May 2025 14:09:18 +0400 Subject: [PATCH 08/10] Migrate TxDelegateTakeRateLimit --- pallets/admin-utils/src/lib.rs | 2 +- pallets/subtensor/src/lib.rs | 2 + .../migrate_obsolete_rate_limiting_maps.rs | 10 ++++ pallets/subtensor/src/tests/migration.rs | 58 +++++++++++++++++++ pallets/subtensor/src/utils/misc.rs | 11 ++-- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 5597dd234f..fcd0570d23 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -1098,7 +1098,7 @@ pub mod pallet { tx_rate_limit: u64, ) -> DispatchResult { ensure_root(origin)?; - pallet_subtensor::Pallet::::set_tx_delegate_take_rate_limit(tx_rate_limit); + pallet_subtensor::Pallet::::set_tx_delegate_take_rate_limit(tx_rate_limit, false); log::debug!( "TxRateLimitDelegateTakeSet( tx_delegate_take_rate_limit: {:?} ) ", tx_rate_limit diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 8e60fb8124..e060aa15d3 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2710,4 +2710,6 @@ pub enum RateLimitKey { SetWeightsRateLimit(u16), // Network rate limits NetworkRateLimit, + // Rate limit for delegate take transactions + TxDelegateRateLimit, } diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs index 6513f4c1aa..db5ac2a047 100644 --- a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -13,8 +13,18 @@ pub fn migrate_obsolete_rate_limiting_maps() -> Weight { .saturating_add(migrate_tx_rate_limits::()) .saturating_add(migrate_set_weights_rate_limits::()) .saturating_add(migrate_network_rate_limits::()) + .saturating_add(migrate_tx_delegate_take_rate_limits::()) } +pub fn migrate_tx_delegate_take_rate_limits() -> Weight { + let migration_name = b"migrate_tx_delegate_take_rate_limits".to_vec(); + let pallet_name = "SubtensorModule"; + let storage_name = "TxDelegateTakeRateLimit"; + + migrate_value::(migration_name, pallet_name, storage_name, |limit| { + Pallet::::set_tx_delegate_take_rate_limit(limit, true); + }) +} pub fn migrate_network_rate_limits() -> Weight { let migration_name = b"migrate_network_rate_limits".to_vec(); let pallet_name = "SubtensorModule"; diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 0da980fb36..83605296d3 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -1059,3 +1059,61 @@ fn test_migrate_network_rate_limit() { assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); } +#[test] +fn test_migrate_tx_delegate_take_rate_limit() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_tx_delegate_take_rate_limits"; + + let pallet_name = "SubtensorModule"; + let storage_name = "TxDelegateTakeRateLimit"; + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let prefix = [pallet_name_hash, storage_name_hash].concat(); + + let mut full_key = prefix.clone(); + + let original_value: u64 = 123; + put_raw(&full_key, &original_value.encode()); + + let stored_before = get_raw(&full_key).expect("Expected RateLimit to exist"); + assert_eq!( + u64::decode(&mut &stored_before[..]).expect("Failed to decode RateLimit"), + original_value + ); + + assert!( + !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should not have run yet" + ); + + // ------------------------------ + // Step 2: Run the Migration + // ------------------------------ + let weight = crate::migrations::migrate_obsolete_rate_limiting_maps:: + migrate_obsolete_rate_limiting_maps::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!( + SubtensorModule::get_tx_delegate_take_rate_limit(), + original_value + ); + assert_eq!( + get_raw(&full_key), + None, + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 499dd20209..00dda68ac4 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -303,11 +303,14 @@ impl Pallet { } } pub fn get_tx_delegate_take_rate_limit() -> u64 { - TxDelegateTakeRateLimit::::get() + LastRateLimitedBlock::::get(RateLimitKey::TxDelegateRateLimit) } - pub fn set_tx_delegate_take_rate_limit(tx_rate_limit: u64) { - TxDelegateTakeRateLimit::::put(tx_rate_limit); - Self::deposit_event(Event::TxDelegateTakeRateLimitSet(tx_rate_limit)); + pub fn set_tx_delegate_take_rate_limit(tx_rate_limit: u64, skip_event: bool) { + LastRateLimitedBlock::::set(RateLimitKey::TxDelegateRateLimit, tx_rate_limit); + + if !skip_event { + Self::deposit_event(Event::TxDelegateTakeRateLimitSet(tx_rate_limit)); + } } pub fn set_min_delegate_take(take: u16) { MinDelegateTake::::put(take); From 425002b68e786af73987ada653a7509af2c1ff83 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Fri, 30 May 2025 14:23:32 +0400 Subject: [PATCH 09/10] Migrate TxChildkeyTakeRateLimit --- pallets/subtensor/src/lib.rs | 2 + pallets/subtensor/src/macros/dispatches.rs | 12 ++-- .../migrate_obsolete_rate_limiting_maps.rs | 10 ++++ pallets/subtensor/src/tests/children.rs | 4 +- pallets/subtensor/src/tests/migration.rs | 59 +++++++++++++++++++ pallets/subtensor/src/utils/misc.rs | 11 ++-- pallets/subtensor/src/utils/rate_limiting.rs | 2 +- 7 files changed, 87 insertions(+), 13 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index e060aa15d3..8f0630d0f8 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2712,4 +2712,6 @@ pub enum RateLimitKey { NetworkRateLimit, // Rate limit for delegate take transactions TxDelegateRateLimit, + // Rate limit for delegate childkey take transactions + TxChildkeyTakeRateLimit, } diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 650fb50451..b8e79f183d 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1045,17 +1045,17 @@ mod dispatches { #[pallet::call_index(69)] #[pallet::weight(( Weight::from_parts(6_873_000, 0) - .saturating_add(T::DbWeight::get().reads(0)) - .saturating_add(T::DbWeight::get().writes(1)), - DispatchClass::Operational, - Pays::No -))] + .saturating_add(T::DbWeight::get().reads(0)) + .saturating_add(T::DbWeight::get().writes(1)), + DispatchClass::Operational, + Pays::No + ))] pub fn sudo_set_tx_childkey_take_rate_limit( origin: OriginFor, tx_rate_limit: u64, ) -> DispatchResult { ensure_root(origin)?; - Self::set_tx_childkey_take_rate_limit(tx_rate_limit); + Self::set_tx_childkey_take_rate_limit(tx_rate_limit, false); Ok(()) } diff --git a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs index db5ac2a047..8302ac2ed9 100644 --- a/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs +++ b/pallets/subtensor/src/migrations/migrate_obsolete_rate_limiting_maps.rs @@ -14,8 +14,18 @@ pub fn migrate_obsolete_rate_limiting_maps() -> Weight { .saturating_add(migrate_set_weights_rate_limits::()) .saturating_add(migrate_network_rate_limits::()) .saturating_add(migrate_tx_delegate_take_rate_limits::()) + .saturating_add(migrate_tx_childkey_take_rate_limit::()) } +pub fn migrate_tx_childkey_take_rate_limit() -> Weight { + let migration_name = b"migrate_tx_childkey_take_rate_limit".to_vec(); + let pallet_name = "SubtensorModule"; + let storage_name = "TxChildkeyTakeRateLimit"; + + migrate_value::(migration_name, pallet_name, storage_name, |limit| { + Pallet::::set_tx_childkey_take_rate_limit(limit, true); + }) +} pub fn migrate_tx_delegate_take_rate_limits() -> Weight { let migration_name = b"migrate_tx_delegate_take_rate_limits".to_vec(); let pallet_name = "SubtensorModule"; diff --git a/pallets/subtensor/src/tests/children.rs b/pallets/subtensor/src/tests/children.rs index ef6add3bf7..227286b925 100644 --- a/pallets/subtensor/src/tests/children.rs +++ b/pallets/subtensor/src/tests/children.rs @@ -934,11 +934,11 @@ fn test_childkey_take_rate_limiting() { // Set a rate limit for childkey take changes let rate_limit: u64 = 100; - SubtensorModule::set_tx_childkey_take_rate_limit(rate_limit); + SubtensorModule::set_tx_childkey_take_rate_limit(rate_limit, false); log::info!( "Set TxChildkeyTakeRateLimit: {:?}", - TxChildkeyTakeRateLimit::::get() + SubtensorModule::get_tx_childkey_take_rate_limit() ); // Helper function to log rate limit information diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 83605296d3..1b13f93135 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -1117,3 +1117,62 @@ fn test_migrate_tx_delegate_take_rate_limit() { assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); } + +#[test] +fn test_migrate_tx_childkey_take_rate_limit() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_tx_childkey_take_rate_limit"; + + let pallet_name = "SubtensorModule"; + let storage_name = "TxChildkeyTakeRateLimit"; + let pallet_name_hash = twox_128(pallet_name.as_bytes()); + let storage_name_hash = twox_128(storage_name.as_bytes()); + let prefix = [pallet_name_hash, storage_name_hash].concat(); + + let mut full_key = prefix.clone(); + + let original_value: u64 = 123; + put_raw(&full_key, &original_value.encode()); + + let stored_before = get_raw(&full_key).expect("Expected RateLimit to exist"); + assert_eq!( + u64::decode(&mut &stored_before[..]).expect("Failed to decode RateLimit"), + original_value + ); + + assert!( + !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should not have run yet" + ); + + // ------------------------------ + // Step 2: Run the Migration + // ------------------------------ + let weight = crate::migrations::migrate_obsolete_rate_limiting_maps:: + migrate_obsolete_rate_limiting_maps::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!( + SubtensorModule::get_tx_childkey_take_rate_limit(), + original_value + ); + assert_eq!( + get_raw(&full_key), + None, + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 00dda68ac4..9a01af43cb 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -336,11 +336,14 @@ impl Pallet { MinChildkeyTake::::get() } pub fn get_tx_childkey_take_rate_limit() -> u64 { - TxChildkeyTakeRateLimit::::get() + LastRateLimitedBlock::::get(RateLimitKey::TxChildkeyTakeRateLimit) } - pub fn set_tx_childkey_take_rate_limit(tx_rate_limit: u64) { - TxChildkeyTakeRateLimit::::put(tx_rate_limit); - Self::deposit_event(Event::TxChildKeyTakeRateLimitSet(tx_rate_limit)); + pub fn set_tx_childkey_take_rate_limit(tx_rate_limit: u64, skip_event: bool) { + LastRateLimitedBlock::::insert(RateLimitKey::TxChildkeyTakeRateLimit, tx_rate_limit); + + if !skip_event { + Self::deposit_event(Event::TxChildKeyTakeRateLimitSet(tx_rate_limit)); + } } pub fn set_min_childkey_take(take: u16) { MinChildkeyTake::::put(take); diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index f1b103ba48..9351df9a13 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -46,7 +46,7 @@ impl Pallet { pub fn get_rate_limit(tx_type: &TransactionType) -> u64 { match tx_type { TransactionType::SetChildren => 150, // 30 minutes - TransactionType::SetChildkeyTake => TxChildkeyTakeRateLimit::::get(), + TransactionType::SetChildkeyTake => Self::get_tx_childkey_take_rate_limit(), TransactionType::RegisterNetwork => Self::get_network_rate_limit(), TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) From 4805bc789632cba5888aa7446b7842e2bce2c50f Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Fri, 30 May 2025 16:01:09 +0400 Subject: [PATCH 10/10] Remove obsolete storage items --- pallets/subtensor/src/lib.rs | 57 ------------------------- pallets/subtensor/src/subnets/subnet.rs | 7 ++- pallets/subtensor/src/utils/misc.rs | 31 ++++++++++++-- precompiles/src/subnet.rs | 5 +-- 4 files changed, 36 insertions(+), 64 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 8f0630d0f8..48b792d278 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -57,7 +57,6 @@ extern crate alloc; pub const MAX_CRV3_COMMIT_SIZE_BYTES: u32 = 5000; -#[allow(deprecated)] #[deny(missing_docs)] #[import_section(errors::errors)] #[import_section(events::events)] @@ -582,14 +581,6 @@ pub mod pallet { T::InitialSubnetOwnerCut::get() } #[pallet::type_value] - /// Default value for network rate limit. - pub fn DefaultNetworkRateLimit() -> u64 { - if cfg!(feature = "pow-faucet") { - return 0; - } - T::InitialNetworkRateLimit::get() - } - #[pallet::type_value] /// Default value for weights version key rate limit. /// In units of tempos. pub fn DefaultWeightsVersionKeyRateLimit() -> u64 { @@ -627,11 +618,6 @@ pub mod pallet { T::InitialTempo::get() } #[pallet::type_value] - /// Default value for weights set rate limit. - pub fn DefaultWeightsSetRateLimit() -> u64 { - 100 - } - #[pallet::type_value] /// Default block number at registration. pub fn DefaultBlockAtRegistration() -> u64 { 0 @@ -771,31 +757,11 @@ pub mod pallet { // T::InitialHotkeyEmissionTempo::get() // } (DEPRECATED) #[pallet::type_value] - /// Default value for rate limiting - pub fn DefaultTxRateLimit() -> u64 { - T::InitialTxRateLimit::get() - } - #[pallet::type_value] - /// Default value for delegate take rate limiting - pub fn DefaultTxDelegateTakeRateLimit() -> u64 { - T::InitialTxDelegateTakeRateLimit::get() - } - #[pallet::type_value] - /// Default value for chidlkey take rate limiting - pub fn DefaultTxChildKeyTakeRateLimit() -> u64 { - T::InitialTxChildKeyTakeRateLimit::get() - } - #[pallet::type_value] /// Default value for last extrinsic block. pub fn DefaultLastTxBlock() -> u64 { 0 } #[pallet::type_value] - /// Default value for serving rate limit. - pub fn DefaultServingRateLimit() -> u64 { - T::InitialServingRateLimit::get() - } - #[pallet::type_value] /// Default value for weight commit/reveal enabled. pub fn DefaultCommitRevealWeightsEnabled() -> bool { false @@ -1212,9 +1178,6 @@ pub mod pallet { #[pallet::storage] /// ITEM( subnet_owner_cut ) pub type SubnetOwnerCut = StorageValue<_, u16, ValueQuery, DefaultSubnetOwnerCut>; - #[pallet::storage] - /// ITEM( network_rate_limit ) - pub type NetworkRateLimit = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit>; #[pallet::storage] // --- ITEM( nominator_min_required_stake ) pub type NominatorMinRequiredStake = StorageValue<_, u64, ValueQuery, DefaultZeroU64>; #[pallet::storage] @@ -1325,11 +1288,6 @@ pub mod pallet { pub type SubnetOwnerHotkey = StorageMap<_, Identity, u16, T::AccountId, ValueQuery, DefaultSubnetOwner>; - #[deprecated] - #[pallet::storage] - /// --- MAP ( netuid ) --> serving_rate_limit - pub type ServingRateLimit = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultServingRateLimit>; #[pallet::storage] /// --- MAP ( netuid ) --> Rho pub type Rho = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultRho>; @@ -1395,10 +1353,6 @@ pub mod pallet { /// --- MAP ( netuid ) --> bonds_reset pub type BondsResetOn = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultBondsResetOn>; - /// --- MAP ( netuid ) --> weights_set_rate_limit - #[pallet::storage] - pub type WeightsSetRateLimit = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsSetRateLimit>; #[pallet::storage] /// --- MAP ( netuid ) --> validator_prune_len pub type ValidatorPruneLen = @@ -1456,17 +1410,6 @@ pub mod pallet { pub type RAORecycledForRegistration = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultRAORecycledForRegistration>; #[pallet::storage] - /// --- ITEM ( tx_rate_limit ) - pub type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; - #[pallet::storage] - /// --- ITEM ( tx_delegate_take_rate_limit ) - pub type TxDelegateTakeRateLimit = - StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; - #[pallet::storage] - /// --- ITEM ( tx_childkey_take_rate_limit ) - pub type TxChildkeyTakeRateLimit = - StorageValue<_, u64, ValueQuery, DefaultTxChildKeyTakeRateLimit>; - #[pallet::storage] /// --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled pub type LiquidAlphaOn = StorageMap<_, Blake2_128Concat, u16, bool, ValueQuery, DefaultLiquidAlpha>; diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index 6f4e95774c..896a8f23d9 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -94,7 +94,12 @@ impl Pallet { } /// Gets the network rate limit pub fn get_network_rate_limit() -> u64 { - LastRateLimitedBlock::::get(RateLimitKey::NetworkRateLimit) + let limit_key = RateLimitKey::NetworkRateLimit; + if !LastRateLimitedBlock::::contains_key(&limit_key) { + return T::InitialNetworkRateLimit::get(); + } + + LastRateLimitedBlock::::get(limit_key) } /// Checks if registrations are allowed for a given subnet. diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 9a01af43cb..b7373fd6c8 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -293,7 +293,12 @@ impl Pallet { // Configure tx rate limiting pub fn get_tx_rate_limit() -> u64 { - LastRateLimitedBlock::::get(RateLimitKey::TxRateLimit) + let limit_key = RateLimitKey::TxRateLimit; + if !LastRateLimitedBlock::::contains_key(&limit_key) { + return T::InitialTxRateLimit::get(); + } + + LastRateLimitedBlock::::get(limit_key) } pub fn set_tx_rate_limit(tx_rate_limit: u64, skip_event: bool) { LastRateLimitedBlock::::set(RateLimitKey::TxRateLimit, tx_rate_limit); @@ -303,7 +308,12 @@ impl Pallet { } } pub fn get_tx_delegate_take_rate_limit() -> u64 { - LastRateLimitedBlock::::get(RateLimitKey::TxDelegateRateLimit) + let limit_key = RateLimitKey::TxDelegateRateLimit; + if !LastRateLimitedBlock::::contains_key(&limit_key) { + return T::InitialTxDelegateTakeRateLimit::get(); + } + + LastRateLimitedBlock::::get(limit_key) } pub fn set_tx_delegate_take_rate_limit(tx_rate_limit: u64, skip_event: bool) { LastRateLimitedBlock::::set(RateLimitKey::TxDelegateRateLimit, tx_rate_limit); @@ -336,7 +346,12 @@ impl Pallet { MinChildkeyTake::::get() } pub fn get_tx_childkey_take_rate_limit() -> u64 { - LastRateLimitedBlock::::get(RateLimitKey::TxChildkeyTakeRateLimit) + let limit_key = RateLimitKey::TxChildkeyTakeRateLimit; + if !LastRateLimitedBlock::::contains_key(&limit_key) { + return T::InitialTxChildKeyTakeRateLimit::get(); + } + + LastRateLimitedBlock::::get(limit_key) } pub fn set_tx_childkey_take_rate_limit(tx_rate_limit: u64, skip_event: bool) { LastRateLimitedBlock::::insert(RateLimitKey::TxChildkeyTakeRateLimit, tx_rate_limit); @@ -363,6 +378,10 @@ impl Pallet { pub fn get_serving_rate_limit(netuid: u16) -> u64 { let limit_key = RateLimitKey::ServingRateLimit(netuid); + if !LastRateLimitedBlock::::contains_key(&limit_key) { + return T::InitialServingRateLimit::get(); + } + Self::get_rate_limited_last_block(&limit_key) } pub fn set_serving_rate_limit(netuid: u16, serving_rate_limit: u64, skip_event: bool) { @@ -399,7 +418,13 @@ impl Pallet { } pub fn get_weights_set_rate_limit(netuid: u16) -> u64 { + const DEFAULT: u64 = 100; let limit_key = RateLimitKey::SetWeightsRateLimit(netuid); + + if !LastRateLimitedBlock::::contains_key(&limit_key) { + return DEFAULT; + } + LastRateLimitedBlock::::get(&limit_key) } pub fn set_weights_set_rate_limit(netuid: u16, weights_set_rate_limit: u64, skip_event: bool) { diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index 6d6cab3e86..ae0d25a5f2 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -1,5 +1,6 @@ use core::marker::PhantomData; +use crate::{PrecompileExt, PrecompileHandleExt}; use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; use frame_support::traits::ConstU32; use frame_system::RawOrigin; @@ -8,8 +9,6 @@ use precompile_utils::{EvmResult, prelude::BoundedString}; use sp_core::H256; use sp_runtime::traits::Dispatchable; -use crate::{PrecompileExt, PrecompileHandleExt}; - pub struct SubnetPrecompile(PhantomData); impl PrecompileExt for SubnetPrecompile @@ -194,7 +193,7 @@ where #[precompile::public("getWeightsSetRateLimit(uint16)")] #[precompile::view] fn get_weights_set_rate_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::WeightsSetRateLimit::::get(netuid)) + Ok(pallet_subtensor::pallet::Pallet::::get_weights_set_rate_limit(netuid)) } #[precompile::public("setWeightsSetRateLimit(uint16,uint64)")]