diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index fe1878f397..c5a92c0b99 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -565,10 +565,10 @@ impl Pallet { NetworkLastLockCost::::get() } pub fn get_network_last_lock_block() -> u64 { - NetworkLastRegistered::::get() + Self::get_rate_limited_last_block(&RateLimitKey::NetworkLastRegistered) } pub fn set_network_last_lock_block(block: u64) { - NetworkLastRegistered::::set(block); + Self::set_rate_limited_last_block(&RateLimitKey::NetworkLastRegistered, block); } pub fn set_lock_reduction_interval(interval: u64) { NetworkLockReductionInterval::::set(interval); @@ -588,10 +588,13 @@ impl Pallet { let halved_interval: I64F64 = interval.saturating_mul(halving); halved_interval.saturating_to_num::() } - pub fn get_rate_limited_last_block(rate_limit_key: &RateLimitKey) -> u64 { + pub fn get_rate_limited_last_block(rate_limit_key: &RateLimitKey) -> u64 { LastRateLimitedBlock::::get(rate_limit_key) } - pub fn set_rate_limited_last_block(rate_limit_key: &RateLimitKey, block: u64) { - LastRateLimitedBlock::::set(rate_limit_key, block); + pub fn set_rate_limited_last_block(rate_limit_key: &RateLimitKey, block: u64) { + LastRateLimitedBlock::::insert(rate_limit_key, block); + } + pub fn remove_rate_limited_last_block(rate_limit_key: &RateLimitKey) { + LastRateLimitedBlock::::remove(rate_limit_key); } } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 4c2eaf0cc7..6f68d0cc1f 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -54,6 +54,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)] @@ -525,11 +526,6 @@ pub mod pallet { T::InitialNetworkImmunityPeriod::get() } #[pallet::type_value] - /// Default value for network last registered. - pub fn DefaultNetworkLastRegistered() -> u64 { - 0 - } - #[pallet::type_value] /// Default value for network min allowed UIDs. pub fn DefaultNetworkMinAllowedUids() -> u16 { T::InitialNetworkMinAllowedUids::get() @@ -1164,10 +1160,6 @@ pub mod pallet { pub type NetworkImmunityPeriod = StorageValue<_, u64, ValueQuery, DefaultNetworkImmunityPeriod>; #[pallet::storage] - /// ITEM( network_last_registered_block ) - pub type NetworkLastRegistered = - StorageValue<_, u64, ValueQuery, DefaultNetworkLastRegistered>; - #[pallet::storage] /// ITEM( min_network_lock_cost ) pub type NetworkMinLockCost = StorageValue<_, TaoCurrency, ValueQuery, DefaultNetworkMinLockCost>; @@ -1200,7 +1192,7 @@ pub mod pallet { #[pallet::storage] /// --- MAP ( RateLimitKey ) --> Block number in which the last rate limited operation occured pub type LastRateLimitedBlock = - StorageMap<_, Identity, RateLimitKey, u64, ValueQuery, DefaultZeroU64>; + StorageMap<_, Identity, RateLimitKey, u64, ValueQuery, DefaultZeroU64>; /// ============================ /// ==== Subnet Locks ===== @@ -1657,14 +1649,17 @@ pub mod pallet { u64, ValueQuery, >; + #[deprecated] #[pallet::storage] /// --- MAP ( key ) --> last_block pub type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + #[deprecated] #[pallet::storage] /// --- MAP ( key ) --> last_tx_block_childkey_take pub type LastTxBlockChildKeyTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + #[deprecated] #[pallet::storage] /// --- MAP ( key ) --> last_tx_block_delegate_take pub type LastTxBlockDelegateTake = @@ -2135,9 +2130,17 @@ impl> /// Enum that defines types of rate limited operations for /// storing last block when this operation occured #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug, TypeInfo)] -pub enum RateLimitKey { +pub enum RateLimitKey { // The setting sn owner hotkey operation is rate limited per netuid SetSNOwnerHotkey(NetUid), + // Subnet registration rate limit + NetworkLastRegistered, + // Last tx block limit per account ID + LastTxBlock(AccountId), + // Last tx block child key limit per account ID + LastTxBlockChildKeyTake(AccountId), + // Last tx block delegate key limit per account ID + LastTxBlockDelegateTake(AccountId), } pub trait ProxyInterface { diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index c842709208..5906abae89 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -2031,7 +2031,7 @@ mod dispatches { /// * commit_reveal_version (`u16`): /// - The client (bittensor-drand) version #[pallet::call_index(113)] - #[pallet::weight((Weight::from_parts(64_530_000, 0) + #[pallet::weight((Weight::from_parts(80_690_000, 0) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn commit_timelocked_weights( diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 4bf7a6b115..88e483475e 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -135,7 +135,9 @@ mod hooks { //Migrate CRV3 to TimelockedCommits .saturating_add(migrations::migrate_crv3_v2_to_timelocked::migrate_crv3_v2_to_timelocked::()) // Migrate to fix root counters - .saturating_add(migrations::migrate_fix_root_tao_and_alpha_in::migrate_fix_root_tao_and_alpha_in::()); + .saturating_add(migrations::migrate_fix_root_tao_and_alpha_in::migrate_fix_root_tao_and_alpha_in::()) + // Migrate last block rate limiting storage items + .saturating_add(migrations::migrate_rate_limiting_last_blocks::migrate_obsolete_rate_limiting_last_blocks_storage::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_rate_limiting_last_blocks.rs b/pallets/subtensor/src/migrations/migrate_rate_limiting_last_blocks.rs new file mode 100644 index 0000000000..99ce1e3077 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_rate_limiting_last_blocks.rs @@ -0,0 +1,161 @@ +use crate::Vec; +use crate::{Config, HasMigrationRun, Pallet}; +use alloc::string::String; +use codec::Decode; +use frame_support::traits::Get; +use frame_support::weights::Weight; +use sp_io::hashing::twox_128; +use sp_io::storage::{clear, get}; + +pub fn migrate_obsolete_rate_limiting_last_blocks_storage() -> Weight { + migrate_network_last_registered::() + .saturating_add(migrate_last_tx_block::()) + .saturating_add(migrate_last_tx_block_childkey_take::()) + .saturating_add(migrate_last_tx_block_delegate_take::()) +} + +pub fn migrate_network_last_registered() -> Weight { + let migration_name = b"migrate_network_last_registered".to_vec(); + let pallet_name = "SubtensorModule"; + let storage_name = "NetworkLastRegistered"; + + migrate_value::(migration_name, pallet_name, storage_name, |limit| { + Pallet::::set_network_last_lock_block(limit); + }) +} + +#[allow(deprecated)] +pub fn migrate_last_tx_block() -> Weight { + let migration_name = b"migrate_last_tx_block".to_vec(); + + migrate_last_block_map::( + migration_name, + || crate::LastTxBlock::::drain().collect::>(), + |account, block| { + Pallet::::set_last_tx_block(&account, block); + }, + ) +} + +#[allow(deprecated)] +pub fn migrate_last_tx_block_childkey_take() -> Weight { + let migration_name = b"migrate_last_tx_block_childkey_take".to_vec(); + + migrate_last_block_map::( + migration_name, + || crate::LastTxBlockChildKeyTake::::drain().collect::>(), + |account, block| { + Pallet::::set_last_tx_block_childkey(&account, block); + }, + ) +} + +#[allow(deprecated)] +pub fn migrate_last_tx_block_delegate_take() -> Weight { + let migration_name = b"migrate_last_tx_block_delegate_take".to_vec(); + + migrate_last_block_map::( + migration_name, + || crate::LastTxBlockDelegateTake::::drain().collect::>(), + |account, block| { + Pallet::::set_last_tx_block_delegate_take(&account, block); + }, + ) +} + +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 '{migration_name:?}' has already run. Skipping.",); + 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 +} + +fn migrate_last_block_map( + migration_name: Vec, + get_values: GetValuesFunction, + set_value: SetValueFunction, +) -> Weight +where + T: Config, + GetValuesFunction: Fn() -> Vec<(T::AccountId, u64)>, // (account, limit in blocks) + SetValueFunction: Fn(T::AccountId, u64), +{ + // 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 '{migration_name:?}' has already run. Skipping.",); + return weight; + } + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + let key_values = get_values(); + weight = weight.saturating_add(T::DbWeight::get().reads(key_values.len() as u64)); + + for (account, block) in key_values.into_iter() { + set_value(account, block); + + 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 65dda18125..ebd7150494 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -22,6 +22,7 @@ pub mod migrate_init_total_issuance; pub mod migrate_orphaned_storage_items; pub mod migrate_populate_owned_hotkeys; pub mod migrate_rao; +pub mod migrate_rate_limiting_last_blocks; pub mod migrate_remove_commitments_rate_limit; pub mod migrate_remove_stake_map; pub mod migrate_remove_total_hotkey_coldkey_stakes_this_interval; diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index 17e349c995..2674d83b60 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -174,7 +174,7 @@ impl Pallet { log::debug!("SubnetMechanism for netuid {netuid_to_register:?} set to: {mechid:?}"); // --- 12. Set the creation terms. - NetworkLastRegistered::::set(current_block); + Self::set_network_last_lock_block(current_block); NetworkRegisteredAt::::insert(netuid_to_register, current_block); // --- 13. Set the symbol. diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index e233460e39..0454b1dd16 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -64,21 +64,18 @@ impl Pallet { ); // 8. Swap LastTxBlock - // LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey. - let last_tx_block: u64 = LastTxBlock::::get(old_hotkey); - LastTxBlock::::insert(new_hotkey, last_tx_block); + let last_tx_block: u64 = Self::get_last_tx_block(old_hotkey); + Self::set_last_tx_block(new_hotkey, last_tx_block); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); // 9. Swap LastTxBlockDelegateTake - // LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take. - let last_tx_block_delegate_take: u64 = LastTxBlockDelegateTake::::get(old_hotkey); - LastTxBlockDelegateTake::::insert(new_hotkey, last_tx_block_delegate_take); + let last_tx_block_delegate_take: u64 = Self::get_last_tx_block_delegate_take(old_hotkey); + Self::set_last_tx_block_delegate_take(new_hotkey, last_tx_block_delegate_take); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); // 10. Swap LastTxBlockChildKeyTake - // LastTxBlockChildKeyTake( hotkey ) --> u64 -- the last transaction block for the hotkey child key take. - let last_tx_block_child_key_take: u64 = LastTxBlockChildKeyTake::::get(old_hotkey); - LastTxBlockChildKeyTake::::insert(new_hotkey, last_tx_block_child_key_take); + let last_tx_block_child_key_take: u64 = Self::get_last_tx_block_childkey_take(old_hotkey); + Self::set_last_tx_block_childkey(new_hotkey, last_tx_block_child_key_take); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); // 11. fork for swap hotkey on a specific subnet case after do the common check @@ -197,17 +194,17 @@ impl Pallet { // 6. Swap LastTxBlock // LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey. - LastTxBlock::::remove(old_hotkey); + Self::remove_last_tx_block(old_hotkey); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // 7. Swap LastTxBlockDelegateTake // LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take. - LastTxBlockDelegateTake::::remove(old_hotkey); + Self::remove_last_tx_block_delegate_take(old_hotkey); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // 8. Swap LastTxBlockChildKeyTake // LastTxBlockChildKeyTake( hotkey ) --> u64 -- the last transaction block for the hotkey child key take. - LastTxBlockChildKeyTake::::remove(old_hotkey); + Self::remove_last_tx_block_childkey(old_hotkey); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // 9. Swap Senate members. diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index e93aab7669..25501eb27a 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -821,6 +821,206 @@ fn test_migrate_remove_commitments_rate_limit() { }); } +#[test] +fn test_migrate_network_last_registered() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_network_last_registered"; + + let pallet_name = "SubtensorModule"; + let storage_name = "NetworkLastRegistered"; + 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_rate_limiting_last_blocks:: + migrate_obsolete_rate_limiting_last_blocks_storage::(); + + 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_last_lock_block(), + 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"); + }); +} + +#[allow(deprecated)] +#[test] +fn test_migrate_last_block_tx() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_last_tx_block"; + + let test_account: U256 = U256::from(1); + let original_value: u64 = 123; + + LastTxBlock::::insert(test_account, 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_rate_limiting_last_blocks:: + migrate_obsolete_rate_limiting_last_blocks_storage::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!( + SubtensorModule::get_last_tx_block(&test_account), + original_value + ); + assert!( + !LastTxBlock::::contains_key(test_account), + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} + +#[allow(deprecated)] +#[test] +fn test_migrate_last_tx_block_childkey_take() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_last_tx_block_childkey_take"; + + let test_account: U256 = U256::from(1); + let original_value: u64 = 123; + + LastTxBlockChildKeyTake::::insert(test_account, 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_rate_limiting_last_blocks:: + migrate_obsolete_rate_limiting_last_blocks_storage::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!( + SubtensorModule::get_last_tx_block_childkey_take(&test_account), + original_value + ); + assert!( + !LastTxBlockChildKeyTake::::contains_key(test_account), + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} + +#[allow(deprecated)] +#[test] +fn test_migrate_last_tx_block_delegate_take() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_last_tx_block_delegate_take"; + + let test_account: U256 = U256::from(1); + let original_value: u64 = 123; + + LastTxBlockDelegateTake::::insert(test_account, 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_rate_limiting_last_blocks:: + migrate_last_tx_block_delegate_take::(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + + assert_eq!( + SubtensorModule::get_last_tx_block_delegate_take(&test_account), + original_value + ); + assert!( + !LastTxBlockDelegateTake::::contains_key(test_account), + "RateLimit storage should have been cleared" + ); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} + #[test] fn test_migrate_fix_root_subnet_tao() { new_test_ext(1).execute_with(|| { diff --git a/pallets/subtensor/src/tests/swap_hotkey.rs b/pallets/subtensor/src/tests/swap_hotkey.rs index 5a9ebf5127..dae5a3f176 100644 --- a/pallets/subtensor/src/tests/swap_hotkey.rs +++ b/pallets/subtensor/src/tests/swap_hotkey.rs @@ -1033,7 +1033,7 @@ fn test_swap_hotkey_error_cases() { // Set up initial state Owner::::insert(old_hotkey, coldkey); TotalNetworks::::put(1); - LastTxBlock::::insert(coldkey, 0); + SubtensorModule::set_last_tx_block(&coldkey, 0); // Test not enough balance let swap_cost = SubtensorModule::get_key_swap_cost(); @@ -1429,11 +1429,11 @@ fn test_swap_hotkey_swap_rate_limits() { let child_key_take_block = 8910; // Set the last tx block for the old hotkey - LastTxBlock::::insert(old_hotkey, last_tx_block); + SubtensorModule::set_last_tx_block(&old_hotkey, last_tx_block); // Set the last delegate take block for the old hotkey - LastTxBlockDelegateTake::::insert(old_hotkey, delegate_take_block); + SubtensorModule::set_last_tx_block_delegate_take(&old_hotkey, delegate_take_block); // Set last childkey take block for the old hotkey - LastTxBlockChildKeyTake::::insert(old_hotkey, child_key_take_block); + SubtensorModule::set_last_tx_block_childkey(&old_hotkey, child_key_take_block); // Perform the swap assert_ok!(SubtensorModule::do_swap_hotkey( @@ -1444,13 +1444,16 @@ fn test_swap_hotkey_swap_rate_limits() { )); // Check for new hotkey - assert_eq!(LastTxBlock::::get(new_hotkey), last_tx_block); assert_eq!( - LastTxBlockDelegateTake::::get(new_hotkey), + SubtensorModule::get_last_tx_block(&new_hotkey), + last_tx_block + ); + assert_eq!( + SubtensorModule::get_last_tx_block_delegate_take(&new_hotkey), delegate_take_block ); assert_eq!( - LastTxBlockChildKeyTake::::get(new_hotkey), + SubtensorModule::get_last_tx_block_childkey_take(&new_hotkey), child_key_take_block ); }); diff --git a/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs b/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs index 314f72c2bd..349c28903a 100644 --- a/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs +++ b/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs @@ -1026,7 +1026,7 @@ fn test_swap_hotkey_error_cases() { // Set up initial state Owner::::insert(old_hotkey, coldkey); TotalNetworks::::put(1); - LastTxBlock::::insert(coldkey, 0); + SubtensorModule::set_last_tx_block(&coldkey, 0); // Test not enough balance let swap_cost = SubtensorModule::get_key_swap_cost(); @@ -1437,11 +1437,11 @@ fn test_swap_hotkey_swap_rate_limits() { SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); // Set the last tx block for the old hotkey - LastTxBlock::::insert(old_hotkey, last_tx_block); + SubtensorModule::set_last_tx_block(&old_hotkey, last_tx_block); // Set the last delegate take block for the old hotkey - LastTxBlockDelegateTake::::insert(old_hotkey, delegate_take_block); + SubtensorModule::set_last_tx_block_delegate_take(&old_hotkey, delegate_take_block); // Set last childkey take block for the old hotkey - LastTxBlockChildKeyTake::::insert(old_hotkey, child_key_take_block); + SubtensorModule::set_last_tx_block_childkey(&old_hotkey, child_key_take_block); // Perform the swap System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -1453,13 +1453,16 @@ fn test_swap_hotkey_swap_rate_limits() { ),); // Check for new hotkey - assert_eq!(LastTxBlock::::get(new_hotkey), last_tx_block); assert_eq!( - LastTxBlockDelegateTake::::get(new_hotkey), + SubtensorModule::get_last_tx_block(&new_hotkey), + last_tx_block + ); + assert_eq!( + SubtensorModule::get_last_tx_block_delegate_take(&new_hotkey), delegate_take_block ); assert_eq!( - LastTxBlockChildKeyTake::::get(new_hotkey), + SubtensorModule::get_last_tx_block_childkey_take(&new_hotkey), child_key_take_block ); }); @@ -1557,7 +1560,6 @@ fn test_swap_hotkey_registered_on_other_subnet() { // Set up initial state Owner::::insert(old_hotkey, coldkey); TotalNetworks::::put(1); - LastTxBlock::::insert(coldkey, 0); let initial_balance = SubtensorModule::get_key_swap_cost().to_u64() + 1000; SubtensorModule::add_balance_to_coldkey_account(&coldkey, initial_balance); diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index eeb5b96ddb..de75086ea1 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -119,14 +119,6 @@ impl Pallet { } } - /// Set the block number of the last transaction for a specific key, and transaction type - pub fn set_last_transaction_block(key: &T::AccountId, tx_type: &TransactionType, block: u64) { - match tx_type { - TransactionType::RegisterNetwork => Self::set_network_last_lock_block(block), - _ => Self::set_last_transaction_block_on_subnet(key, NetUid::ROOT, tx_type, block), - } - } - /// Set the block number of the last transaction for a specific hotkey, network, and transaction type pub fn set_last_transaction_block_on_subnet( key: &T::AccountId, @@ -146,20 +138,39 @@ impl Pallet { } } + pub fn remove_last_tx_block(key: &T::AccountId) { + Self::remove_rate_limited_last_block(&RateLimitKey::LastTxBlock(key.clone())) + } pub fn set_last_tx_block(key: &T::AccountId, block: u64) { - LastTxBlock::::insert(key, block) + Self::set_rate_limited_last_block(&RateLimitKey::LastTxBlock(key.clone()), block); } pub fn get_last_tx_block(key: &T::AccountId) -> u64 { - LastTxBlock::::get(key) + Self::get_rate_limited_last_block(&RateLimitKey::LastTxBlock(key.clone())) + } + + pub fn remove_last_tx_block_delegate_take(key: &T::AccountId) { + Self::remove_rate_limited_last_block(&RateLimitKey::LastTxBlockDelegateTake(key.clone())) } pub fn set_last_tx_block_delegate_take(key: &T::AccountId, block: u64) { - LastTxBlockDelegateTake::::insert(key, block) + Self::set_rate_limited_last_block( + &RateLimitKey::LastTxBlockDelegateTake(key.clone()), + block, + ); } pub fn get_last_tx_block_delegate_take(key: &T::AccountId) -> u64 { - LastTxBlockDelegateTake::::get(key) + Self::get_rate_limited_last_block(&RateLimitKey::LastTxBlockDelegateTake(key.clone())) } pub fn get_last_tx_block_childkey_take(key: &T::AccountId) -> u64 { - LastTxBlockChildKeyTake::::get(key) + Self::get_rate_limited_last_block(&RateLimitKey::LastTxBlockChildKeyTake(key.clone())) + } + pub fn remove_last_tx_block_childkey(key: &T::AccountId) { + Self::remove_rate_limited_last_block(&RateLimitKey::LastTxBlockChildKeyTake(key.clone())) + } + pub fn set_last_tx_block_childkey(key: &T::AccountId, block: u64) { + Self::set_rate_limited_last_block( + &RateLimitKey::LastTxBlockChildKeyTake(key.clone()), + block, + ); } pub fn exceeds_tx_rate_limit(prev_tx_block: u64, current_block: u64) -> bool { let rate_limit: u64 = Self::get_tx_rate_limit();